Mysql Update Query for sample table - mysql

I have 1 table called sample and it has 3 columns.
id customer default_address
1 1 0
2 1 0
3 1 0
4 1 0
5 2 0
6 2 0
7 3 0
8 3 0
9 2 0
10 2 0
Here I want to group by customer and update first default address should be 1 and rest all for 0 for every customer. How to do it mysql query?
Thanks

UPDATE tb a
LEFT JOIN
(
SELECT customer, MIN(id) id
FROM tb
GROUP BY customer
) b ON a.customer = b.customer AND
a.ID = b.ID
SET a.default_address = b.ID IS NOT NULL
SQLFiddle Demo

UPDATE sample
LEFT JOIN
(SELECT MIN(id) id,customer
FROM sample
GROUP BY customer) t ON sample.customer=t.customer
SET default_address="1"
WHERE sample.id=t.id;
This should work.

Update Table1
INNER JOIN (Select Min(`id`) as MinID,`customer`
From Table1 Group by `customer`) t2
SET Table1.`default_address` = 1
WHERE Table1.`id` = t2.MinID;
SAMPLE FIDDLE

Related

Updating table based on same table with a max value

Have a table data structure like below:
id
regid
docid
archived
1
1000
1
0
2
1000
2
0
3
1000
3
0
4
2000
1
0
5
2000
2
0
6
3000
1
0
7
3000
2
0
8
3000
3
0
9
3000
4
0
What I'm trying to do update the archived column to 1 where the docid is less than the max docid, by each regid group.
So I should end up with id's 3, 5 & 9 not being set to 1
Have tried:
update table t1
join (select max(docid) as maxdocid, regid from table) t2 on t1.docid < t2.maxdocid and t1.regid = t2.regid
set t1.archived = 1
But doesn't work, only does the first regid group.
Here's a solution (in MySQL 8.0+) using a CTE:
WITH numbered_table AS (
SELECT id, ROW_NUMBER() OVER (PARTITION BY regid ORDER BY docid DESC) AS rownum
FROM mytable
)
UPDATE mytable JOIN numbered_table USING (id)
SET archived = 1
WHERE rownum > 1
AND archived = 0;
Second solution, if you use an older version of MySQL that doesn't support CTE syntax:
You don't really need to compute the max docid value. If you want to update all rows except for the row with the max docid value, then you can check if a row can be matched to any other row with a greater docid value.
UPDATE mytable AS t1
INNER JOIN mytable AS t2 ON t1.regid = t2.regid AND t1.docid < t2.docid
SET t1.archived = 1
WHERE t1.archived = 0;
This will be true for all rows except the row with the max value. That row will be excluded automatically by the join.
In steps:
Create a query with the MAX value, per docid:
SELECT
ID,
regid,
docid,
(SELECT MAX(docid) FROM t1 te where te.regid=t.regid) as M
FROM t1 t
Join the result, and update:
UPDATE t1
JOIN (
SELECT
ID,
regid,
docid,
(SELECT MAX(docid) FROM t1 te where te.regid=t.regid) as M
FROM t1 t
) x ON t1.id=x.id
SET archived = 1
WHERE t1.docid<x.M AND t1.archived=0;
see: DBFIDDLE
You could try:
update test_tbl t1
set t1.archived = 1
where t1.archived = 0
and t1.id not in ( select t2.id
from (select max(id) as id,
regid,
max(docid)
from test_tbl
group by regid
) as t2
) ;
Result:
id regid docid archived
1 1000 1 1
2 1000 2 1
3 1000 3 0
4 2000 1 1
5 2000 2 0
6 3000 1 1
7 3000 2 1
8 3000 3 1
9 3000 4 0
Demo
Or you can use a LEFT JOIN
update test_tbl t1
left join ( select max(id) as id,
regid,
max(docid) as docid
from test_tbl
group by regid
) as t2 on t1.id=t2.id
set t1.archived = 1
where t1.archived = 0
and t2.id IS NULL
Demo
Use a self join in the update statement:
UPDATE tablename t1
INNER JOIN tablename t2
ON t2.regid = t1.regid AND t2.docid > t1.docid
SET t1.archived = 1;
See the demo.

How to fetch the last row MySQL

I have 100k Data; this is all just my example
I have this 2 tables
I want to check into my table2 if the schedule exists in my table1.
If it exists the last schedule will be the output with remarks = 'OK' and Balance = '0'
my sample query:
select *
from table2 as A
join table1 as B ON A.ID = B.ID
where A.Remarks = 'OK'
and A.Schedule = (select max(schedule) from table1)
and A.balance = '0'
and B.Balance = 0
the output should be like this
ID
Schedule
BALANCE
Remarks
1
5
0
OK
TABLE1
ID
Schedule
BALANCE
Remarks
1
1
0
OK
1
2
0
OK
1
3
0
OK
1
4
0
OK
1
5
0
OK
2
6
100
NOT_OK
TABLE2
ID
Schedule
BALANCE
Remarks
1
1
0
OK
1
2
0
OK
Select A.ID,
max(B.Schedule),
A.Balance,
A.Remarks
from table2 as A
join table1 as B ON A.ID = B.ID
Where A.Remarks = 'OK'
and A.Balance = '0'
and B.Balance = 0
Group By A.ID,
A.Balance,
A.Remarks

Two where condition for same column using group by

I am having two tables, t1, t2. My tables and expected result are given below.
My table schema is in sqlfiddle
t1:
id branch_name
1 branch1
2 branch2
3 branch3
4 branch4
5 branch5
t2:
id VBRNCH VTOBRN vqty
1 1 0 10
2 2 0 20
3 3 0 30
4 0 4 40
5 0 5 50
Expected Result is:
branch_name send received
1 10 0
2 20 0
3 30 0
4 0 40
5 0 50
What i have tried is:
SELECT
b1.branch_name,
i1.vqty AS send,
i2.vqty AS received
FROM t2 i1
INNER
JOIN t1 b1
ON b1.id = i1.VBRNCH
INNER JOIN t2 i2
ON b1.id = i2.VTOBRN
GROUP
BY i1.VTOBRN,
i2.VBRNCH;
But I am getting zero rows.
I think this is the query you are looking for:
SELECT t1.branch_name,
COALESCE(SUM(send.vqty), 0) AS send,
COALESCE(SUM(receive.vqty), 0) AS received
FROM t1
LEFT JOIN t2 AS send on t1.id = send.VBRNCH
LEFT JOIN t2 AS receive on t1.id = receive.VTOBRN
GROUP BY t1.branch_name
Demo here
E.g.
SELECT x.*
, COALESCE(sent,0) sent
, COALESCE(received,0) received
FROM t1 x
LEFT
JOIN
( SELECT from_br
, SUM(vqty) sent
FROM t2
GROUP
BY from_br
) a
ON a.from_br = x.id
LEFT
JOIN
( SELECT to_br
, SUM(vqty) received
FROM t2
GROUP
BY to_br
) b
ON b.to_br = x.id
ORDER
BY id;
http://sqlfiddle.com/#!9/af0973/21

Grab top row from GROUP BY

Going off of my last question: Complex Grouping in SQL Query…
In each grouping, I'd like to grab only the row with the highest 'step' value.
This is the query we came up with in the last question:
SELECT a.*, b.*
FROM (
SELECT request_id
FROM tableA
GROUP BY request_id
HAVING MAX(page_views) <= 0 AND MAX(step) <= 2
) AS sumQ
INNER JOIN tableA AS a ON sumQ.request_id = a.request_id
INNER JOIN tableB AS b ON a.request_id = b.id
That returns:
id request_id page_views step name phone
----------------------------------------------------------------
8 3 0 0 Jacob Clark 434-343-434
9 3 0 1 Jacob Clark 434-343-434
10 4 0 0 Alex Smith 222-112-2112
11 4 0 1 Alex Smith 222-112-2112
12 4 0 2 Alex Smith 222-112-2112
Which is what I wanted, however, I realized that in each group (group by request_id) I only need the row with the highest 'step' value. How can I modify my existing query to return only:
id request_id page_views step name phone
----------------------------------------------------------------
9 3 0 1 Jacob Clark 434-343-434
12 4 0 2 Alex Smith 222-112-2112
?
Then include step in the logic:
SELECT a.*, b.*
FROM (SELECT request_id, MAX(step) as maxstep
FROM tableA
GROUP BY request_id
HAVING MAX(page_views) <= 0 AND MAX(step) <= 2
) sumQ INNER JOIN
tableA a
ON sumQ.request_id = a.request_id AND
sumQ.maxstep = a.step INNER JOIN
tableB b
ON a.request_id = b.id;
Have you tried setting an ORDER BY on the step field and then take the TOP record?
SELECT a.*, b.*
FROM (
SELECT TOP 1 request_id
FROM tableA
GROUP BY request_id
HAVING MAX(page_views) <= 0 AND MAX(step) <= 2
ORDER BY step DESC
) AS sumQ
INNER JOIN tableA AS a ON sumQ.request_id = a.request_id
INNER JOIN tableB AS b ON a.request_id = b.id

Mysql group_concat for count in sub query using parent filed is not allowed

I need to process album count for each of the country per artist; however, I have a problem once I do group_concat for count in mysql, I search a bit in stackoverflow, I found I have to do sub select for group_concat. The problem is once I do the sub select in from I can not use a.id from the parent from filed table. I got error like following Unknown column 'a.id' in 'where clause'
This is the query:
SELECT a.seq_id, a.id
(SELECT GROUP_CONCAT(cnt) AS cnt FROM (
SELECT CONCAT_WS('-', mgr.country_code, count(mgr.media_id)) AS cnt
FROM music_album_artists AS ma
JOIN media_geo_restrict AS mgr ON ma.album_id = mgr.media_id
WHERE ma.artist_id = a.id
GROUP BY mgr.country_code
) count_table
) AS album_count
FROM music_artist AS a
WHERE a.seq_id > 0 and a.seq_id < 10000
The sample data in tables:
music_artists:
seq_id id name
1 1 Hola
2 2 Vivi
music_album_artists:
id artist_id album_id
1 1 1
2 1 2
3 1 5
4 1 10
5 2 2
6 2 10
6 2 1
media_geo_restrict:
album_id country_code
1 BE
1 CA
1 DE
1 US
2 CH
2 CA
2 CH
5 DE
10 US
The result I would like to have
seq_id id album_count
1 1 BE--1,CA--2,CH--1,DE--1,US--1
2 2 CA--1,US--2,CH--1
Here is what you need:
select seq_id, id, group_concat(concat(country_code, '--', qtd))
from (
select ma.seq_id, ma.id,
mgr.country_code, count(*) qtd
from music_artists ma
inner join music_album_artists maa
on ma.id = maa.artist_id
inner join media_geo_restrict mgr
on maa.album_id = mgr.album_id
where ma.seq_id > 0 and ma.seq_id < 10000
group by ma.seq_id, ma.id, ma.name,
mgr.country_code
) tb
group by seq_id, id
Here is the working sample: http://sqlfiddle.com/#!9/ff8b5/8
Try this and tell me:
SELECT a.seq_id, a.id, GROUP_CONCAT(cnt) AS cnt
FROM music_artist AS a,
(
SELECT ma.artist_id, CONCAT_WS('-', mgr.country_code, count(mgr.media_id)) AS cnt
FROM music_album_artists AS ma
JOIN media_geo_restrict AS mgr ON ma.album_id = mgr.album_id
GROUP BY mgr.country_code
) AS count_table
WHERE a.seq_id > 0 and a.seq_id < 10000
and a.id=count_table.artist_id
group by a.id