2013-10-15 26 views
1

我有四个表部门,团队,费用和收入。MY sql sumif return double count

出发表:

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

您正在创建一个多分支连接树,其中d-> m-> e和d-> m-> ex。这可能会导致这样的奇怪结果。 –

+0

@Marc B是的,但是解决方案是什么? – Zia

+0

不要做多分支连接。做一个'select * from ....'没有总和,你会发现当你做多分支时结果看起来有多疯狂。 –

回答

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) 
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 
+0

出发列是varchar,而我没有得到这个结果。 – Zia