Two where condition for same column using group by - mysql

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

Related

How to get result from query group by sql without return duplicate

i have 3 table that will join into 1 table.
table1
id|prdct_name|qty
001 A 5
002 B 5
003 C 5
table2
id|prdct_id|price
1 001 100
2 001 200
3 002 150
4 002 250
table3
id|prdct_id|stock_in|stock_out
1 001 5 0
2 001 10 0
3 002 15 0
4 002 25 0
I have tried this sql (updated due to typo)
select a.prdct_name as Name, a.qty as QTY,b.price as PRICE, c.stock_in as SIN,c.stock_out as SOUT
from table1 a
left join table2 b on a.id=b.prdct_id
left join table3 c on a.id=c.prdct_id
where 1=1 group by b.id,c.id
but result return duplicate like this table
NAME|QTY|PRICE|SIN|SOUT
A 5 100 5 0
A 5 100 10 0
A 5 200 5 0
A 5 200 10 0
B 5 150 15 0
B 5 150 25 0
B 5 250 15 0
B 5 250 25 0
the result should be
NAME|QTY|PRICE|SIN|SOUT
A 5 100 5 0
A 5 200 10 0
B 5 150 15 0
B 5 250 25 0
is there a way to remove the duplicate issue? trying with distinct also not help.
Thanks
It looks like your second join should be on id -- and your join conditions don't look right anyway.
select a.prdct_name as Name, a.qty as QTY, b.price as PRICE, c.stock_in as SIN,c.stock_out as SOUT
from table1 a left join
table2 b
on a.id = b.prdct_id left join
table3 c
on a.id = c.id
where 1=1
group by b.id, c.id
change your join key it should id =product_id but you are trying with name & product_id
select a.prdct_name as Name, a.qty as QTY,b.price as PRICE, c.stock_in as SIN,c.stock_out as SOUT
from table1 a
left join table2 b on a.id=b.prdct_id
left join table3 c on a.id=c.prdct_id
where 1=1 group by b.id,c.id
You can make use of the SQL keyword DISTINCT to select non-duplicate rows.
Example:
SELECT DISTINCT
prdct_name as NAME,
qty as QTY,
price as PRICE,
stock_in as SIN,
stock_out as SOUT
FROM
table1 a
INNER JOIN
table2 b ON a.id=b.prdct_id
LEFT JOIN
table3 c ON b.id=c.id
GROUP BY
a.id, c.id
Working SQL fiddle
More about DISTINCT here.

MYSQL filter multiply row by two lists of id

I have results:
item_id subitem_id
----------------------
1 35
1 25
1 8
2 10
2 25
3 60
4 35
4 25
4 44
5 1
5 23
5 15
5 13
5 9
and I have two lists of subitem
(25,44,1)
(8,9)
how do I set the where clause in order to filter the result and return this
item_id subitem_id
----------------------
1 35
1 25 <-- first set
1 8 <-- second set
-----------------
5 1 <-- first set
5 23
5 15
5 13
5 9 <-- second set
because this item_id contain both subitem_id from two lists
SELECT
`item_id`
FROM table
WHERE `subitem_id` in (25,44,1)
AND `subitem_id` in (8,9)
Did not work, because in one time subitem_id have one id (not all list)
P.S.
This is a simple example, in reality we have more than 100k records with some join construction
http://sqlfiddle.com/#!9/71c28e5/3
SELECT t1.*
FROM (
SELECT DISTINCT(t1.item_id)
FROM t1
INNER JOIN t1 t2
ON t1.item_id = t2.item_id
AND t2.subitem_id in (8,9)
WHERE t1.subitem_id in (25,44,1)
) t
LEFT JOIN t1
ON t.item_id = t1.item_id
Another approach to avoid big number of executed records for mysql:
http://sqlfiddle.com/#!9/71c28e5/10
SELECT t1.*
FROM t1
WHERE item_id in (
SELECT DISTINCT(t1.item_id)
FROM t1
INNER JOIN t1 t2
ON t1.item_id = t2.item_id
AND t2.subitem_id in (25,44,1)
WHERE t1.subitem_id in (8,9)
)
SQL Fiddle
I think you're trying to make sure a item_ID has subcategories in 2 differen sets..
Select * from table A
where exists (Select 1 from table B where A.Item_Id = B.Item_ID and subitem_ID in (25,44,1))
and exists (Select 1 from table C where A.Item_Id = C.Item_ID and subitem_ID in (8,9))

Can I GROUP BY in MySQL, but have it ignore null values when grouping, dropping a result row if necessary?

My tables:
t1
col_a col_b
1 100
1 200
1 300
2 400
t2
col_a col_b
100 5
100 6
t3
col_a col_b
5 100
6 200
6 300
If I run a query and left join the 3 tables in order i get:
1 100 5 100
1 100 6 200
1 100 6 300
1 200 null null
1 300 null null
2 400 null null
If I add group by t1.col_a, t2.col_b:
1 100 5 100
1 100 6 (200 or 300)
1 (200 or 300) null null
2 400 null null
But I don't want to the 3rd row to show because it does not have a value in t2.col_b. I could add a condition to where that column is not null, but that would remove the last row which needs to stay.
In a perfect query I would like to see:
1 100 5 100
1 100 6 (200 or 300)
2 400 null null
Try this one. t1.col_b is a little tricky, because if multiple t1.col_a values exists with none reference to t2, this query select a random for this.
SELECT
sub.col_a,
IFNULL(sub.relation,t1.col_b),
t2.col_b,
t3.col_b
FROM(
SELECT
t1.col_a,
group_concat(DISTINCT t2.col_a) AS relation
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.col_a = t1.col_b
GROUP BY t1.col_a
) AS sub
LEFT JOIN table1 AS t1
ON t1.col_a = sub.col_a
AND (t1.col_b IN (sub.relation) OR sub.relation IS NULL)
LEFT JOIN table2 AS t2
ON t2.col_a = t1.col_b
LEFT JOIN table3 AS t3
ON t3.col_a = t2.col_b
GROUP BY t1.col_a, t2.col_b
One approach is to select only the non-null rows as a part of the result, then union it with a broader - but grouped - set of results:
SELECT * FROM t1
JOIN t2 ON t1.col_b = t2.col_a
LEFT JOIN t3 ON t2.col_b = t3.col_a
UNION
SELECT * FROM t1
LEFT JOIN t2 ON t1.col_b = t2.col_a
LEFT JOIN t3 ON t2.col_b = t3.col_a
GROUP BY t1.col_a
Notice that the first query does not have a LEFT JOIN. That's because we don't want any NULL results in that query. That query gives you:
t1.col_a t2.col_a t3.col_a t3.col_b
1 100 5 100
1 100 6 200
1 100 6 300
And the second query gives you:
t1.col_a t2.col_a t3.col_a t3.col_b
1 100 5 100
2 400 NULL NULL
Finally, when you do a UNION, it gets rid of the duplicate result (first row in first result set is equal to the first row in the second result set). This is the default behavior of the UNION command, resulting in:
t1.col_a t2.col_a t3.col_a t3.col_b
1 100 5 100
1 100 6 200
1 100 6 300
2 400 NULL NULL

Difference tabels based on Id and unixtimestamp

My table is looking as folowing:
unix_timestap ID value
1351058019 1 500
1351058029 1 505
1351058039 9 105
1351058049 9 200
1351076620 1 520
I would like be able to generate a new column contain the differences between the values per ID between the current value and the first available "past" value. With past I mean that unixtimestamp is not placed in order in the original table.
The output would be:
unix_timestap ID value difference
1351058019 1 500 0
1351058029 1 505 5
1351058039 9 105 0
1351058049 9 200 95
1351076620 1 520 15
If no previous unix_timestamp exists, the value should be zero.
A Hint/tip would be much appreciated.
Thanks
if solution still needed
select
t3.unix_timestamp, t3.id, t3.value, ifnull(t3.value - t5.value, 0) as diff
from test1 t3
join (
SELECT t1.unix_timestamp, t1.id, max(t2.unix_timestamp) as old_stamp
FROM `test1` t1
left join test1 t2 on t1.id = t2.id and t1.unix_timestamp > t2.unix_timestamp
group by t1.unix_timestamp, t1.id) as t4
on t3.unix_timestamp = t4.unix_timestamp and t3.id = t4.id
left join test1 t5 on t4.old_stamp = t5.unix_timestamp and t4.id = t5.id

how is this query done in mysql?

Given the following table ...
ID USER NUM
1 1 69
2 2 75
3 3 7
4 1 31
5 2 18
6 3 70
7 1 12
8 2 23
9 3 42
... which query would return rows with the lowest NUM for each USER?
The result should look like ...
ID USER NUM
7 1 12
5 2 18
3 3 7
Can't wrap my head around this one! Assuming it has a GROUP BY, but everything I try fails... Any pointers?
SELECT t.*
FROM tablename t
INNER JOIN (SELECT user, MIN(num) num
FROM tablename
GROUP BY user) x ON t.user = x.user AND t.num = x.num
or
SELECT t1.*
FROM tablename t1
LEFT JOIN tablename t2 ON t1.user = t2.user AND t1.num > t2.num
WHERE t2.id IS NULL
SELECT ID , MIN(NUM) as MIN_NUM , USER FROM usertable GROUP BY USER
Have a look at demo http://sqlfiddle.com/#!2/ce2fd/1
HEre is another method. UPDATED WITH THE CORRECT REREFERENCE
SQLFIDDLE
Query
select b.id, a.user, a.minnum from
mytable as b
join
(select user, min(num) as minnum
from mytable
group by user
) as a
on b.user = a.user
where b.num = a.minnum
order by a.minnum asc
limit 3
;
Results:
ID USER MINNUM
3 3 7
7 1 12
5 2 18