2013-01-14 2 views
1
SELECT bi.id, 
     bi.location, 
     bi.expense_group, 
     bi.level, 
     bi.is_active, 
     bi.type, 
     full_name, 
     Sum(DISTINCT bl.amount)          AS 
     BudgetAmount, 
     Sum(DISTINCT Ifnull((bl.amount * 6) - (+ bal1.amount + bal2.amount + 
               bal3.amount 
               + bal4.amount + bal5.amount + 
               bal6.amount), 0)) AS 
     Difference, 
     Sum(DISTINCT Ifnull(Round((+ bal1.amount + bal2.amount + bal3.amount 
            + bal4.amount + bal5.amount + bal6.amount)/
           6), 0) 
     )               AS Average, 
     Sum(DISTINCT bal1.amount)         AS BAL1, 
     Sum(DISTINCT bal2.amount)         AS BAL2, 
     Sum(DISTINCT bal3.amount)         AS BAL3, 
     Sum(DISTINCT bal4.amount)         AS BAL4, 
     Sum(DISTINCT bal5.amount)         AS BAL5, 
     Sum(DISTINCT bal6.amount)         AS BAL6 
FROM (SELECT * 
     FROM budget_items 
     WHERE bi.location IS NOT NULL) AS bi 
     LEFT JOIN budget_lines AS bl 
       ON bi.id = bl.budget_item_id 
       AND bl.budget_id = 5983 
     LEFT JOIN balance_lines AS bal1 
       ON bi.id = bal1.budget_item_id 
       AND bal1.balance_id = 28839 
     LEFT JOIN balance_lines AS bal2 
       ON bi.id = bal2.budget_item_id 
       AND bal2.balance_id = 28633 
     LEFT JOIN balance_lines AS bal3 
       ON bi.id = bal3.budget_item_id 
       AND bal3.balance_id = 26664 
     LEFT JOIN balance_lines AS bal4 
       ON bi.id = bal4.budget_item_id 
       AND bal4.balance_id = 14500 
     LEFT JOIN balance_lines AS bal5 
       ON bi.id = bal5.budget_item_id 
       AND bal5.balance_id = 10199 
     LEFT JOIN balance_lines AS bal6 
       ON bi.id = bal6.budget_item_id 
       AND bal6.balance_id = 7204 
GROUP BY bi.id 
ORDER BY bi.position 

실제로 볼 수있는 것처럼 3 개의 테이블 만 있지만 각 저울에 대해 하나씩 쿼리해야합니다. 시간이 오래 걸립니다. 내 실수는 어디 갔지?MySQL LEFT JOIN 쿼리가 매우 느립니다.


@ Gordon Linoff 게시물에 어려움을 겪은 후 직접 수정하려고했습니다. @ 고든 리노프는 그게 무슨 뜻이야?

 SELECT bi.id, 
     bi.location, 
     bi.expense_group, 
     bi.level, 
     bi.is_active, 
     bi.type, 
     full_name, 
     (bl.bud_amount) AS BudgetAmount, 
     (coalesce((bl.bud_amount * 6) - (bal.bal_amount1 + bal.bal_amount2 + bal.bal_amount3 + bal.bal_amount4 + bal.bal_amount5 + bal.bal_amount6), 
        0)) AS Difference, 
     (coalesce(Round((bal.bal_amount1 + bal.bal_amount2 + bal.bal_amount3 + bal.bal_amount4 + bal.bal_amount5 + bal.bal_amount6)/
           6), 0) 
      ) AS Average, 
     bal.bal_amount1         AS BAL1, 
     bal.bal_amount2         AS BAL2, 
     bal.bal_amount3         AS BAL3, 
     bal.bal_amount4         AS BAL4, 
     bal.bal_amount5         AS BAL5, 
     bal.bal_amount6         AS BAL6 
FROM (SELECT * 
     FROM budget_items bi 
     WHERE bi.location IS NOT NULL 
    ) AS bi 

    LEFT JOIN 
    (select budget_item_id, Sum(case when budget_id = 5983 then amount end) AS bud_amount 
    from budget_lines 
     group by budget_item_id 
    ) AS bl 
    on bl.budget_item_id = bi.id 

    JOIN 
    (select budget_item_id, 
      IFNULL(Sum(case when balance_id = 28839 then amount end), 0) AS bal_amount1, 
      IFNULL(Sum(case when balance_id = 28633 then amount end), 0) AS bal_amount2, 
      IFNULL(Sum(case when balance_id = 26664 then amount end), 0) AS bal_amount3, 
      IFNULL(Sum(case when balance_id = 14500 then amount end), 0) AS bal_amount4, 
      IFNULL(Sum(case when balance_id = 10199 then amount end), 0) AS bal_amount5, 
      IFNULL(Sum(case when balance_id = 7204 then amount end), 0) AS bal_amount6 
     from balance_lines 
     group by budget_item_id 
    ) AS bal 
    on bal.budget_item_id = bi.id 
ORDER BY bi.location 
+0

인덱스 확인 – ic3b3rg

+0

어떤 플랫폼 (MySQL, MSSQL, Oracle)을 사용하고 있습니까? – Kermit

+0

IfNull에서 MySQL처럼 보입니다. – DWright

답변

2

언제든지 sum(distinct . . .)에 문제가있는 것입니다. 왼쪽 외부 조인에서 카티 션 곱을 얻고 있고 동일한 양의 두 줄이 있으면 전체 결과가 정확하지 않습니다.

select budget_item_id, 
     Sum(case when budget_id = 5983 then amount end) AS BAL, 
     Sum(case when budget_id = 28839 then amount end) AS BAL1, 
     Sum(case when budget_id = 28633 then amount end) AS BAL2, 
     Sum(case when budget_id = 26664 then amount end) AS BAL3, 
     Sum(case when budget_id = 14500 then amount end) AS BAL4, 
     Sum(case when budget_id = 10199 then amount end) AS BAL5, 
     Sum(case when budget_id = 7204 then amount end) AS BAL6 
from balance_lines 
group by budget_item_id 

을하고 쿼리의 나머지 부분을 수정 :

나는이 같은 하위 쿼리와 조인 모든 왼쪽 외부를 교체 할 생각합니다.

다음은 쿼리 작성 시도입니다. 나는 완전히 bi.id 예산 항목 테이블에 고유 키는 가정, 외부 group by을 제거

SELECT bi.id, 
     bi.location, 
     bi.expense_group, 
     bi.level, 
     bi.is_active, 
     bi.type, 
     full_name, 
     (bl.bal) AS BudgetAmount, 
     (coalesce((bl.bal * 6) - (bl.bal1 + bl.bal2 + bl.bal3 + bl.bal4 + bl.bal5 + bl.bal6), 
        0)) AS Difference, 
     (coalesce(Round((bl.bal1 + bl.bal2 + bl.bal3 + bl.bal4 + bl.bal5 + bl.bal6)/
           6), 0) 
      ) AS Average, 
     bl.bal1         AS BAL1, 
     bl.bal2         AS BAL2, 
     bl.bal3         AS BAL3, 
     bl.bal4         AS BAL4, 
     bl.bal5         AS BAL5, 
     bl.bal6         AS BAL6 
FROM (SELECT * 
     FROM budget_items bi 
     WHERE bi.location IS NOT NULL 
    ) bi left outer join 
    (select budget_item_id, 
      Sum(case when budget_id = 5983 then amount end) AS BAL, 
      Sum(case when budget_id = 28839 then amount end) AS BAL1, 
      Sum(case when budget_id = 28633 then amount end) AS BAL2, 
      Sum(case when budget_id = 26664 then amount end) AS BAL3, 
      Sum(case when budget_id = 14500 then amount end) AS BAL4, 
      Sum(case when budget_id = 10199 then amount end) AS BAL5, 
      Sum(case when budget_id = 7204 then amount end) AS BAL6 
     from balance_lines 
     group by budget_item_id 
    ) bal 
    on bal.budget_item_id = bi.id 
ORDER BY bi.position 

참고 :이 의심 할 여지없이 구문 오류가 있습니다.

+0

문제를 완벽하게 이해 한 것 같습니다. 동일한 금액을 공유하는 회선에 문제가 있습니다. 솔루션에 따라 전체 쿼리를 작성할 수 있습니까? 나는 그것을 고칠 방법이 확실하지 않기 때문에 큰 도움이 될 것입니다. –

+0

음. 당신이 한 일을 완전히 이해하지 못하기 때문에 나는 그것을 고칠 수 없다 :-(또한 첫 번째 BAL (5983)은 나의 첫번째 게시물에서 볼 수있는 다른 테이블에서 온다 - budget_lines balance_lines가 아닐 수도 있습니다. 아마도 오류의 원인 일 수 있습니다. 도움을 주시면 감사하겠습니다. 동적으로 쿼리를 생성하기 때문에 2 (bal1 및 bal2)로 충분하게 작성할 수 있습니까? –

+0

또 다른 질문 : LEFT JOIN을 지우고 JOIN 만 사용했는데, 예산 항목을 모두 줄 것인가? LEFT JOIN을 사용해야한다고 생각했습니다. 감사합니다. –