我的sql sumif返回双重计数

时间:2013-10-15 16:22:34

标签: mysql

我有四个表部门,团队,费用和收入。

离开表:

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

但是在一些离开时查询返回总奖金的双倍金额。这个查询有什么错误的帮助?

2 个答案:

答案 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)