我有四个表部门,团队,费用和收入。
离开表:
id depart
团队表:
id name depart_id
费用表:
id team_id expense_type amount date
和收入表:
id team_id earning_type earning_peace date
我想计算离去的总费用金额和总收入和平。我使用这个查询:
SELECT d.id, d.depart,
SUM(if(`earning_type` = 1, earning_peace, 0)) as earning_peace1,
SUM(if(`earning_type` = 2, earning_peace, 0)) as earning_peace2,
SUM(if(`earning_type` = 3, earning_peace, 0)) as earning_peace3,
SUM(if(`earning_type` = 4, earning_peace, 0)) as earning_peace4,
SUM(if(`expense_type` = 1, amount, 0)) as `expense1`,
SUM(if (`expense_type` = 2, amount, 0)) as expense2,
SUM(if (`expense_type` = 3, amount, 0)) as expense3,
SUM(if (`expense_type` = 4, amount, 0)) as expense4
FROM depart d INNER JOIN team m ON d.id = m.depart_id
LEFT JOIN earning e ON m.id = e.team_id
LEFT JOIN expense ex ON ex.team_id = m.id
GROUP BY d.id
但是在一些离开时查询返回总奖金的双倍金额。这个查询有什么错误的帮助?
答案 0 :(得分:1)
正如@MarcB评论您正在创建一个多分支连接树。我认为如果你单独执行聚合然后结合结果会更好:
SELECT
d.id,
d.depart,
ea.earning_peace1,
ea.earning_peace2,
ea.earning_peace3,
ea.earning_peace4,
ex.expense1,
ex.expense2,
ex.expense3,
ex.expense4
FROM
depart d
LEFT JOIN (
SELECT
t.depart_id,
SUM(if(`earning_type` = 1, earning_peace, 0)) as earning_peace1,
SUM(if(`earning_type` = 2, earning_peace, 0)) as earning_peace2,
SUM(if(`earning_type` = 3, earning_peace, 0)) as earning_peace3,
SUM(if(`earning_type` = 4, earning_peace, 0)) as earning_peace4
FROM
earning e
INNER JOIN team t ON t.id = e.team_id
GROUP BY t.depart_id
) ea ON ea.depart_id = d.id
LEFT JOIN (
SELECT
t.depart_id,
SUM(if(`expense_type` = 1, amount, 0)) as `expense1`,
SUM(if (`expense_type` = 2, amount, 0)) as expense2,
SUM(if (`expense_type` = 3, amount, 0)) as expense3,
SUM(if (`expense_type` = 4, amount, 0)) as expense4
FROM
expense x,
INNER JOIN team t ON t.id = x.team_id
GROUP BY t.depart_id
) ex ON ex.depart_id = d.id
答案 1 :(得分:1)
这是一个很大的数据集可能会很慢的一个技巧,但正确的索引可以为它提供实时,分别为收入和费用制作数据集,然后加入两个数据集
SELECT * FROM
(SELECT d.id AS did, d.depart,
SUM( CASE WHEN `expense_type` = 1 THEN amount ELSE 0 END ) AS `expense1`,
SUM( CASE WHEN `expense_type` = 2 THEN amount ELSE 0 END ) AS `expense2`,
SUM( CASE WHEN `expense_type` = 3 THEN amount ELSE 0 END ) AS `expense3`,
SUM( CASE WHEN `expense_type` = 4 THEN amount ELSE 0 END ) AS `expense4`
FROM depart d
LEFT JOIN team m ON d.id = m.depart_id
LEFT JOIN earning e ON m.id = e.team_id
GROUP BY d.id
) expensetable
INNER JOIN
(
SELECT d.id AS did, d.depart,
SUM( CASE WHEN `earning_type` = 1 THEN earning_peace ELSE 0 END ) AS earning_peace1,
SUM( CASE WHEN `earning_type` = 2 THEN earning_peace ELSE 0 END ) AS earning_peace2,
SUM( CASE WHEN `earning_type` = 3 THEN earning_peace ELSE 0 END ) AS earning_peace3,
SUM( CASE WHEN `earning_type` = 4 THEN earning_peace ELSE 0 END ) AS earning_peace4
FROM depart d
LEFT JOIN team m ON d.id = m.depart_id
LEFT JOIN expense ex ON ex.team_id = m.id
GROUP BY d.id
) earningtable ON (expensetable.did = earningtable.did)