1

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

出发表:

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

但是查询在某些出发时返回总收入的两倍。此查询中的错误有什么帮助?

4

2 回答 2

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
于 2013-10-15T16:27:33.730 回答
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)
于 2013-10-15T17:56:59.933 回答