[英]mysql select query with sum and group by from two columns
我有一张名为 ward 的桌子
+---------+-----------+
| ward_id | ward_name |
+---------+-----------+
| 3 | Ward 1 |
| 4 | Ward 2 |
+---------+-----------+
+----+----------+----------------+---------+---------+--------------+------------+
| id | username | date_allocated | ward_id | shop_id | food_name | amount |
+----+----------+----------------+---------+---------+--------------+------------+
| 1 | STORE1 | 2020-04-06 | 4 | 2 | Beans | 1000 Bags |
| 2 | STAMP | 2020-04-21 | 4 | 2 | Maize Grains | 60 bags |
| 3 | STORE1 | 2020-04-21 | 4 | 2 | Maize Flour | 120 bags |
| 4 | STORE1 | 2020-04-21 | 4 | 2 | Wheat Flour | 120 bags |
| 5 | STAMP | 2020-04-24 | 3 | 2 | Maize Flour | 50 bales |
| 6 | STAMP | 2020-04-25 | 4 | 2 | Maize Flour | 1000 Bales |
| 7 | STAMP | 2020-04-25 | 4 | 2 | Wheat Flour | 150 pkts |
+----+----------+----------------+---------+---------+--------------+------------+
用过的食物
+----+----------+------------+---------+---------+---------+-------------+-----------+
| id | username | date_spent | idno | ward_id | shop_id | food_name | amount |
+----+----------+------------+---------+---------+---------+-------------+-----------+
| 5 | STAMP | 2020-04-21 | 3000000 | 4 | 2 | Beans | 50 pkts |
| 6 | STAMP | 2020-04-21 | 3000000 | 4 | 2 | Maize Flour | 1000 Bags |
| 7 | STAMP | 2020-04-24 | 3000000 | 3 | 2 | Wheat Flour | 4 Packets |
| 8 | STAMP | 2020-04-25 | 3000000 | 3 | 3 | Maize Flour | 50 bales |
| 9 | STAMP | 2020-04-25 | 3000000 | 3 | 3 | Wheat Flour | 50 pkts |
| 10 | STAMP | 2020-04-25 | 3000000 | 4 | 2 | Wheat Flour | 120 Bales |
+----+----------+------------+---------+---------+---------+-------------+-----------+
我创建了一个查询
SELECT ward.ward_name, ward.ward_id,
food_allocation.food_name, food_allocation.ward_id, spent_food.food_name,
sum(food_allocation.tot1) as food,
sum(spent_food.tot2) as spent,
sum(food_allocation.tots-spent_food.tots) as Balance
FROM ward
INNER JOIN (
SELECT ward_id,food_name,
sum(amount) tot1,
sum(amount) tots
FROM food_allocation
GROUP BY food_name,ward_id
) food_allocation ON ward.ward_id = food_allocation.ward_id
INNER JOIN (
SELECT ward_id,food_name,
sum(amount) tot2,
sum(amount) tots
FROM spent_food
GROUP BY food_name, ward_id
) spent_food ON food_allocation.ward_id = spent_food.ward_id
GROUP BY food_allocation.ward_id, food_allocation.food_name
ORDER BY food_allocation.ward_id;
我在下面得到这个错误的数字
+-----------+---------+--------------+---------+-------------+------+-------+---------+
| ward_name | ward_id | food_name | ward_id | food_name | food | spent | Balance |
+-----------+---------+--------------+---------+-------------+------+-------+---------+
| Ward 1 | 3 | Maize Flour | 3 | Maize Flour | 100 | 104 | -4 |
| Ward 2 | 4 | Beans | 4 | Beans | 3000 | 1170 | 1830 |
| Ward 2 | 4 | Maize Flour | 4 | Beans | 3360 | 1170 | 2190 |
| Ward 2 | 4 | Maize Grains | 4 | Beans | 180 | 1170 | -990 |
| Ward 2 | 4 | Wheat Flour | 4 | Beans | 810 | 1170 | -360 |
+-----------+---------+--------------+---------+-------------+------+-------+---------+
我的预期答案是
+-----------+---------+--------------+---------+-------------+------+-------+---------+
| ward_name | ward_id | food_name | ward_id | food | spent | Balance |
+-----------+---------+--------------+---------+-------------+------+-------+---------+
| Ward 1 | 3 | Maize Flour | 3 | 50 | 50 | 0 |
| Ward 2 | 4 | Beans | 4 | 1000 | 50 | 950 |
| Ward 2 | 4 | Maize Flour | 4 | 1120 | 1000 | 120 |
| Ward 2 | 4 | Maize Grains | 4 | 60 | 0 | 60 |
| Ward 2 | 4 | Wheat Flour | 4 | 270 | 120 | 150 |
+-----------+---------+--------------+---------+-------------+------+-------+---------+
当您在最后一张桌子上加入 Sped_food 时,您必须在正确的地方加入他们,即 ward_id 和 food_name。
仅供参考,我缩短了表格的名称,这样我的文字就更少了,而且阅读起来好多了
SELECT w.ward_name, w.ward_id,
f.food_name
, MAX(f.ward_id)
, MAX(s.food_name),
sum(f.tot1) as food,
sum(s.tot2) as spent,
sum(f.tots-s.tots) as Balance
FROM ward w
INNER JOIN (
SELECT ward_id,food_name,
sum(amount) tot1,
sum(amount) tots
FROM food_allocation
GROUP BY food_name,ward_id
) f ON w.ward_id = f.ward_id
INNER JOIN (
SELECT ward_id,food_name,
sum(amount) tot2,
sum(amount) tots
FROM spent_food
GROUP BY food_name, ward_id
) s ON f.ward_id = s.ward_id AND f.food_name = s.food_name
GROUP BY w.ward_name, w.ward_id, f.food_name
ORDER BY f.ward_id;
您必须将连接转换为左连接,并在正确的列上连接查询。
另外,由于您在每个子查询中进行聚合,因此不需要最终聚合,因此我删除了最后一个GROUP BY
:
SELECT w.ward_name,
w.ward_id,
fa.food_name,
coalesce(fa.tot1,0) as food,
coalesce(sf.tot2,0) as spent,
coalesce(fa.tots,0)-coalesce(sf.tots,0) as Balance
FROM ward w
LEFT JOIN (
SELECT ward_id,food_name,
sum(amount) tot1,
sum(amount) tots
FROM food_allocation
GROUP BY food_name,ward_id
) fa ON w.ward_id = fa.ward_id
LEFT JOIN (
SELECT ward_id,food_name,
sum(amount) tot2,
sum(amount) tots
FROM spent_food
GROUP BY food_name, ward_id
) sf ON fa.ward_id = sf.ward_id AND fa.food_name = sf.food_name
ORDER BY fa.ward_id, fa.food_name;
见演示。
结果:
> ward_name | ward_id | food_name | food | spent | Balance
> :-------- | ------: | :----------- | ---: | ----: | ------:
> Ward 1 | 3 | Maize Flour | 50 | 50 | 0
> Ward 2 | 4 | Beans | 1000 | 50 | 950
> Ward 2 | 4 | Maize Flour | 1120 | 1000 | 120
> Ward 2 | 4 | Maize Grains | 60 | 0 | 60
> Ward 2 | 4 | Wheat Flour | 270 | 120 | 150
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.