2013-10-15 3 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

Смежные вопросы