How to use sum of values in SQL joins in same table - mysql

I'm trying to update a field in the database to the sum of its joined values:
I have this sample data:
ID refer_id my_reflink s1 s2 m1 m2
-----------------------------------------------
1 a 1 7
2 a b 2 8
3 a c 3 9
4 d 4 0
5 b e 5 1
6 c f 6 2
I need a query that gives this result to s1 and s2.
ID refer_id my_reflink s1 s2 m1 m2
----------------------------------------------------
1 a 5 17 1 7
2 a b 5 1 2 8
3 a c 0 0 3 9
4 d 4 0
5 b e 6 2 5 1
6 e f 0 0 6 2
The result is
s1 = sum of m1 for refer_id = my_reflink for each ID
s2 = sum of m2 for refer_id = my_reflink for each ID
So for ID1, it will be
s1 = 5 because ID 2 and ID 3 have my_reflink of ID 1 and m1 = 2 m1 = 3
s2 = 17 because ID 2 and ID 3 have my_reflink of ID 1 and m2 = 8 m2 = 9

The update/join syntax might be different depending on the RDBMS used but the below query works for MySql
UPDATE someTable t
JOIN (SELECT refer_id, SUM(m1) sum_m1, SUM(m2) sum_m2
FROM someTable
GROUP BY refer_id) s ON s.refer_id = t.my_reflink
SET s1 = COALESCE(sum_m1, 0), s2 = COALESCE(sum_m2,0)

You seem to want a join:
select t.ID, t.refer_id, t.my_reflink, tt.m1, tt.m2,
t.m1, t.m2
from t left join
(select refer_id, sum(m1) as m1, sum(m2) as m2
from t
group by refer_id
) tt
on t.my_reflink = tt.refer_id;
If you want to actually change the data (rather than return a result set), then the update syntax depends on the database you are using.

Related

subtract from values by groups

What is the best way to subtract the lowest value from all values by group?
Something like:
ID Name Value
1 A 10
1 B 40
1 C 100
2 A 20
2 B 80
2 C 90
3 A 4
3 B 7
3 C 8
turn to:
ID Name Value
1 A 0
1 B 30
1 C 90
2 A 0
2 B 60
2 C 70
3 A 0
3 B 3
3 C 4
Use window functions:
select id, name, value - min(value) over (partition by id) as
from t;
If you actually want to update the values, in MySQL, aggregation and join are probably the simplest solution:
update t join
(select id, min(value) as min_value
from t
group by id
) tt
on t.id = tt.id
set value = value - min_value
where min_value <> 0;

How to list all children with their root parent in a hierarchy using mysql query

I have a mysql database table which has list of locations with there parent location id in hierarchical manner so i want to list all the locations with their root parent location
Following is the sample table
id location_name parent_id
1 a 0
2 b 0
3 c 0
4 d 1
5 e 1
6 f 5
7 g 4
8 k 2
9 l 8
10 j 9
Following is the result i want
id location_name root_parent_name
1 a a
2 b b
3 c c
4 d a
5 e a
6 f a
7 g a
8 k b
9 l b
10 j b
parent name is root parent location
Try the following
SELECT t1.name as parent, t2.`name` as name FROM `test` t1 RIGHT JOIN `test` t2 ON t2.`p_id` = t1.id

mysql query not working as expected complex

I have 3 tables in which all 3 tables are joined to get the result.
Below is the table,
//tbl_order
order_id order_no_first order_no order_no_last order_date
---------------------------------------------------------------------
1 C 1000 a 2017-05-16
2 C 1001 a 2017-05-16
3 C 1001 b 2017-05-16
4 A 1002 a 2017-05-16
5 A 1002 b 2017-05-16
//tbl_assign
assign_id order_id order_no_first central_status central_assign_unit
----------------------------------------------------------------------------
1 1 C 1 1
2 2 C 1 1
3 3 C 1 1
4 4 A 1 1
//tbl_unit_status
status_id assign_id status_status
---------------------------------------
1 1 Cutter
2 1 Stitch
3 1 Delivery
4 2 Cutter
5 2 Stitch
6 3 Cutter
7 4 Cutter
I want the result as below,
//Required output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
from the table tbl_unit_status the status below status_status field, if it is Despatch then do not display that result.
I have tried to get the above result. But no success below is my code.
`SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND a.central_assign_unit = 1
OR (u2.status_status != "Delivery" AND u2.status_status != "Despatch")
GROUP BY o.order_id
From the above code, the result is
//wrong output
order_id assign_id order_no_first order_no order_no_last status_status
---------------------------------------------------------------------------
1 1 C 1000 a Delivery
2 2 C 1001 a Stitch
3 3 C 1001 b Cutter
4 4 A 1002 a Cutter
5 A 1002 b
Is there any way to get the Required output as soon in the first output. I have tried and am stuck in here.
Thank you.
Use parenthesis correctly arround AND OR clauses and I recommend using NOT LIKE instead of != when dealing with strings.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id AND o.order_no_first = a.order_no_first
LEFT JOIN (
SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u GROUP BY u.assign_id) uu
ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2 on u2.status_id = uu.maxid
WHERE a.central_status = 1 AND (a.central_assign_unit = 1 OR u2.status_status NOT LIKE 'Delivery' AND u2.status_status NOT LIKE 'Despatch')
GROUP BY o.order_id
Obs: I can't comment due to my reputation, I'm sorry
You should be using AND instead of OR in your where clause. You don't need the parentheses either.
SELECT *
FROM tbl_order o
LEFT JOIN tbl_assign a
ON a.order_id = o.order_id
AND o.order_no_first = a.order_no_first
LEFT JOIN
(SELECT u.assign_id, max(u.status_id) AS maxid
FROM tbl_unit_status u
GROUP BY u.assign_id
) uu ON uu.assign_id = a.assign_id
LEFT JOIN tbl_unit_status u2
on u2.status_id = uu.maxid
WHERE a.central_status = 1
AND a.central_assign_unit = 1
AND (
u2.status_status IS NULL
OR
u2.status_status NOT IN ("Delivery", "Despatch")
)
GROUP BY o.order_id

Identical values in one column and unique value pairs

I have 2 columns
A B
1 2
2 2
1 2
3 2
5 2
0 2
4 2
11 4
12 4
11 4
I want the SQL query to return the pairs (A,B) where:
B has appeared 3 or more times
AND (A,B) is unique
The resulting table would be:
A B
1 2
2 2
3 2
5 2
0 2
4 2
You could use a join with a selected table grouped by B having count = 3
select distinct A, B
from my_table as t1
inner join (
select b
from my_table
group by b
having count(*)= 3
) t2 on t2.b = t1.b
and for 3 or more
select distinct A, B
from my_table as t1
inner join (
select b
from my_table
group by b
having count(*) >= 3
) t2 on t2.b = t1.b

Unioning and Joining in 1 Query?

I have the following tables:
TABLE1:
A B C
1 2 3
2 4 6
3 6 9
TABLE2:
A B C
4 8 12
5 10 15
6 12 18
TABLE3:
A D
2 X
4 Y
6 Z
I need one query that gives:
A B C D
1 2 3
2 4 6 X
3 6 9
4 8 12 Y
5 10 15
6 12 18 Z
Is that possible?
I can do it in 2 queries, but the person I'm doing it for wants it in 1.
Thanks!
Try this (example on sqlfiddle):
SELECT x.a, x.b, x.c, d
FROM (
SELECT a, b, c FROM table1
UNION ALL
SELECT a, b, c FROM table2
) x
LEFT JOIN table3 ON ( table3.a = x.a )
Sure:
select v1.*, table3.d
from
(select table1.a, table1.b, table1.c
from table1
union all
select table2.a, table2.b, table2.c
from table2
) v1
left join table3 on v1.a = table3.a