I have a two table and I have left join and want sum of value from both table.
But the result from second table not retrieved successfully (SUM not group by properly)
Table test1
id redeem_count cost camp_id
1 2 500 1
2 3 1000 1
3 2 2000 2
4 2 3000 2
5 2 1200 3
Table test2
id bill_amount earning test1_id
1 4000 50 1
2 5000 55 3
3 6000 60 4
Output
camp_id redeem cost bill earning
1 5 1500 15000 165
2 4 5000 NULL NULL
3 2 1200 NULL NULL
Desired Result
camp_id redeem cost bill earning
1 5 1500 4000 50
2 4 5000 11000 115
3 2 1200 0 0
I have execute following SQL.
SELECT
t1.camp_id,
t1.redeem,
t1.cost,
t2.bill,
t2.earning
FROM (SELECT COALESCE(SUM(redeem_count),0) AS redeem, COALESCE(SUM(cost),0) AS cost, id,camp_id FROM test1 GROUP BY camp_id) t1
LEFT JOIN(SELECT COALESCE(SUM(bill_amount),0) AS bill, COALESCE(SUM(earning),0) AS earning, test1_id FROM test2) t2
ON t1.id = t2.test1_id
How can I achieve desired result? Would you please provide the solution?
SELECT
t1.camp_id,
t1.redeem,
t1.cost,
t2.bill,
t2.earning
FROM (SELECT COALESCE(SUM(redeem_count),0) AS redeem, COALESCE(SUM(cost),0) AS cost, id,camp_id FROM test1 GROUP BY camp_id) t1
LEFT JOIN(SELECT COALESCE(bill_amount) AS bill, COALESCE(earning) AS earning, test1_id FROM test2) t2
ON t1.id = t2.test1_id
try this:
SELECT
t1.camp_id,
t1.redeem,
t1.cost,
t2.bill,
t2.earning
FROM (SELECT COALESCE(SUM(redeem_count),0) AS redeem, COALESCE(SUM(cost),0) AS cost, id,camp_id FROM test1 GROUP BY camp_id) t1
LEFT JOIN(SELECT COALESCE(bill_amount) AS bill, COALESCE(earning) AS earning, test1_id FROM test2) t2
ON t1.id = t2.test1_id
update:1
SELECT
t1.camp_id,
t1.redeem,
t1.cost,
t2.bill,
t2.earning
FROM
(
SELECT
COALESCE(SUM(redeem_count),0) AS redeem,
COALESCE(SUM(cost),0) AS cost,
id,
camp_id
FROM test1
GROUP BY camp_id) t1
LEFT JOIN(
SELECT
SUM(bill_amount) AS bill,
SUM(earning) AS earning, test1_id FROM test2 GROUP BY test1_id) t2
ON t1.camp_id= t2.test1_id
My code produced output like:
camp_id redeem cost bill earning
1 5 1500 4000 50
2 4 5000 11000 115
3 2 1200 (NULL) (NULL)
EDITED
Create your subquery like when you want to query only the required result, then join those results.
(Query is not tested!)
SELECT
X1.camp_id
, X1.redeem
, X1.redeem
, X2.cost
, X2.earning
FROM
(
SELECT
SUM(redeem_count) AS redeem,
SUM(cost) AS cost,
id,
camp_id
FROM
test1
GROUP BY
camp_id
) X1
LEFT JOIN (
SELECT
T1.camp_id,
SUM(T2.bill_amount) AS bill,
SUM(T2.earning) AS earning
FROM
test1 T1
INNER JOIN test2 T2
ON T1.id = T2.id
GROUP BY
T1.camp_id
) X2
ON X1.camp_id = X2.camp_id
Related
I am trying to make a query for getting data from 3 tables. Here are the sample tables:
Table 1:
id
user_id
date
amount
1
1
15.01.2021
1000
2
1
16.01.2021
1000
3
2
17.01.2021
1000
4
1
17.01.2021
1000
5
3
22.01.2021
1000
Table 2:
id
user_id
date
amount
1
1
17.01.2021
50
2
1
20.01.2021
50
3
2
21.01.2021
100
4
1
21.01.2021
75
Now I need to make a query that can give the following output using these 2 tables:
Result:
user_id
date
T1.amount
T2.amount
1
15.01.2021
1000
NULL
1
16.01.2021
1000
NULL
1
17.01.2021
1000
50
2
17.01.2021
1000
NULL
1
20.01.2021
NULL
50
2
21.01.2021
NULL
100
1
21.01.2021
NULL
75
3
22.01.2021
1000
NULL
I have tried with Join and Union but no luck. Thanks in Advance
Please try this,
SELECT
A.USER_ID
,A.DATE
,B.AMOUNT AS AMOUNT_1
,C.AMOUNT AS AMOUNT_2
FROM
(
SELECT USER_ID
,DATE
FROM TABLE_1
UNION
SELECT USER_ID
,DATE
FROM TABLE_2
)A
LEFT JOIN
TABLE_1 B
ON A.USER_ID=B.USER_ID AND A.DATE=B.DATE
LEFT JOIN
TABLE_2 C
ON A.USER_ID=C.USER_ID AND A.DATE=C.DATE
GROUP BY A.USER_ID
,A.DATE
, B.AMOUNT
,C.AMOUNT
Union first providing dummy columns then group by
with cte as
(
select user_id,date,amount amt1 , null amt2 from t
union all
select user_id,date,null amt1 , amount amt2 from t1
)
select user_id,date,sum(amt1),sum(amt2)
from cte
group by user_id,date;
I have 3 tables like:
owner_details:-
owner_id owner_name
---------------------
1 A
2 B
3 C
-------------------
vehicle_owner:-
v_id vehicle_id owner_id
-------------------------
1 1 1
2 2 2
3 4 1
4 3 1
5 5 3
transaction:-
id v_id amount transaction_type
--------------------------------
1 1 100 0
2 2 250 1
3 1 150 1
4 3 450 1
5 1 200 0
6 4 300 1
7 5 150 0
8 5 200 1
transaction_type= 0 then (-) transaction_type=1 then (+)
Owner A (1) have 3 vehicles with v_id (1,3,4) in table vehicle_owner.
v_id (1,3,4) have 5 entries in table transaction (1,3,4,5,6) with sum of amount 600 (-100+150+450-200+300)
Now I want listing like this:-.
owner_id owner_name amount
---------------------
1 A 600
2 B 250
3 C 50
-------------------
You can use the following query:
SELECT od.owner_id, od.owner_name, SUM(t.amount) AS amount
FROM owner_details od INNER JOIN vehicle_owner vo ON od.owner_id = vo.owner_id
INNER JOIN `transaction` t ON vo.v_id = t.v_id
GROUP BY od.owner_id
If you want to use the additional transaction_type you can use the following:
SELECT od.owner_id, od.owner_name, SUM(CASE WHEN t.transaction_type = 0 THEN t.amount * -1 ELSE t.amount END) AS amount
FROM owner_details od INNER JOIN vehicle_owner vo ON od.owner_id = vo.owner_id
INNER JOIN `transaction` t ON vo.v_id = t.v_id
GROUP BY od.owner_id
demo: http://sqlfiddle.com/#!9/c5f8d/1/1
Try this:
SELECT A.owner_id, A.owner_name, SUM(IFNULL(amount,0)) AMOUNT
FROM owner_details A LEFT JOIN
vehicle_owner B
ON A.owner_id=B.owner_id
LEFT JOIN `transaction` C
ON C.v_id=B.v_id
GROUP BY A.owner_id, A.owner_name;
It works for me
SELECT od.owner_id,
od.owner_name,
Sum(t.amount) AS amount
FROM owner_details od
INNER JOIN vehicle_owner vo
ON od.owner_id = vo.owner_id
INNER JOIN (SELECT v_id,
Coalesce(Sum(CASE
WHEN type = 0 THEN -amount
ELSE +amount
end), 0.0) AS amount
FROM `transaction`
GROUP BY v_id) t
ON vo.v_id = t.v_id
GROUP BY od.owner_id
Thanks Sebastian Brosch for quick response !!!
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))
I've two tables named table1 and table2. table2 may have elements from table1. I'd like to show all the results from table2 with the price if available in table1 and with status 1. If no product matches in table1 and also status is 0, need to return price as 0.
table1
id pname item_code price status
1 product1 abcd 200 1
2 product2 pqrs 500 1
3 product3 wxyz 425 1
4 product5 mnop 100 0
and table2 as follows
id item_code
10 efgh
11 abcd
12 pqrs
13 mnop
I have tried following query
SELECT `t2`.`id`, `t2`.`item_code`, `t1`.`price`,`t1`.`pname`, COUNT(t2.item_code) AS sellers FROM (`table2` as t2) LEFT JOIN `table1` as t1 ON `t1`.`item_code` = `t2`.`item_code` WHERE `t1`.`status` = 1 GROUP BY `t2`.`item_code`
but it returns common values in table1 and table2 with status 1, but I need all records from table2 with price as 0 if nothing match in table1 or status 0 in table1.
Expected output
id item_code price
10 efgh 0
11 abcd 200
12 pqrs 500
13 mnop 0
Any help please.
Thanks,
Not sure about your current query which is having count and group by however you can do as below
select
t2.id,
t2.item_code,
case
when t1.status = 1 then t1.price
else 0
end as price
from table2 t2
left join table1 t1 on t1.item_code = t2.item_code
Now note that if table1 has multiple matching values from table2 in that case we may need grouping data.
Try below query:
SELECT `t2`.`id`, `t2`.`item_code`, `t1`.`price`,`t1`.`pname`, COUNT(t2.item_code) AS sellers FROM (`table2` as t2) LEFT JOIN (select * from table1 where status = 1)t1 ON `t1`.`item_code` = `t2`.`item_code` GROUP BY `t2`.`item_code`
Move the part of the WHERE clause that checks the left joined table to the ON clause
SELECT `t2`.`id`, `t2`.`item_code`, COALESCE(`t1`.`price`, 0),`t1`.`pname`, COUNT(t2.item_code) AS sellers
FROM (`table2` as t2)
LEFT JOIN `table1` as t1
ON `t1`.`item_code` = `t2`.`item_code`
AND`t1`.`status` = 1
GROUP BY `t2`.`item_code`
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