2009-07-08 5 views
3

두 개의 테이블이 있습니다. 하나는 모든 지사가 있고 다른 하나는 모든 판매입니다. 판매 테이블에는 영업 담당자 ID, 지점 ID, 월 및 연도도 포함됩니다.T-SQL, 조인시 일치하지 않는 부분의 합계가

1 년 동안 특정 담당자의 매출 합계를 분기 및 월별로 그룹화하여 반환하는 쿼리가 필요하며 해당 분기의 영업이없는 경우 쿼리는 0을 반환해야합니다. 판매가가없는 경우 I는 0을 반환하지 않습니다 다음을 가지고 :

SELECT 
    s.Month, 
    b.BranchName, 
    SUM(s.InvoiceAmount) AS 'Sales' 
FROM 
    Branch b 
INNER JOIN 
    Sales s ON s.BranchID = b.BranchID 
WHERE 
    s.Year = 2008 
AND 
    s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    s.Month, 
    b.BranchName 
+0

SELECT 목록의 s.Month가 누락 되었습니까? – pjp

+0

실수로 예 s.Month가 SELECT – staterium

+0

(OP에서 수정 됨) – staterium

답변

4

"누락 된"데이터를 추가해야 참여할 수 있습니다.

SELECT 
    b.BranchName, 
    SUM(ISNULL(s.InvoiceAmount, 0)) AS 'Sales', 
    s.Month 
FROM 
    Branch b 
    LEFT OUTER JOIN (
      SELECT 
     b.BranchID AS BranchID 
     , s.SalesRepID AS SalesRepID 
     , Months.Month AS Month 
     , Years.Year AS Year 
     , 0 AS InvoiceAmount 
     FROM 
      Sales s 
      CROSS JOIN (
      SELECT 1 AS Month 
      UNION ALL SELECT 2 
      UNION ALL SELECT 3 
      UNION ALL SELECT 4 
      UNION ALL SELECT 5 
      UNION ALL SELECT 6 
      UNION ALL SELECT 7 
      UNION ALL SELECT 8 
      UNION ALL SELECT 9 
      UNION ALL SELECT 10 
      UNION ALL SELECT 11 
      UNION ALL SELECT 12 
      ) Months 
      CROSS JOIN (
      SELECT 2007 AS Year 
      UNION ALL SELECT 2008 
      UNION ALL SELECT 2009 
      ) Years 
      CROSS JOIN Branch b 
     UNION ALL SELECT 
     s.BranchID AS BranchID 
     , s.SalesRepID AS SalesRepID 
     , s.Month AS Month 
     , s.Year AS Year 
     , s.InvoiceAmount AS InvoiceAmount 
     FROM Sales s  
    )s ON s.BranchID = b.BranchID  
WHERE 
    s.Year = 2008 
    AND s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    b.BranchName, 
    s.Month 
+0

나는 비슷한 것을 게시하려하고 있었다. – pjp

+1

나는 혼자만의 질문을 해석하지 않았다. 다른 모든 대답은 InvoiceAmount의 NULL 값에 초점을 맞추는 것처럼 보입니다. 나는 이것이 영업 이익이 의미하는 바가 아닌지 의심 스럽다. –

+0

감사합니다 Lieven, 그 작품 (일종의). 이제 해당 담당자가 해당 지점에서 판매하지 않은 달에 대해 0 값을 얻지 만 전체적으로 쿼리는 해당 지점의 영업일 지점에서 분기를 반환합니다. – staterium

2

의 모든 기록이없는 심지어 담당자를 반환하기 위해 당신은 판매에 가입을 왼쪽으로 수행해야합니다 판매 테이블.

+0

왼쪽 조인은 최종 쿼리에 판매가없는 분기를 추가해야하며 집계가 반환됩니다. – Spence

+0

-1 s.SalesRepId에는 where 절이 있으므로 Sales에 대한 왼쪽 외부 조인은 무의미합니다. – pjp

1

쿼리는 NULL을 반환하는 경우에는 병합 방법 중 하나를 사용할 수 있습니다 : 목록의 첫 번째 NULL이 아닌 값을 반환합니다 COALESCE(SUM(...), 0)을 ...

+0

합체가 합계 안에 들어 있으면 안됩니다. 또는 합계가 NULL 값을 합계 할 수 있습니다. SQL Sever에서 경고가 발생한다는 사실을 알고 있습니다. – pjp

+0

경고 : Null 값은 집계 또는 다른 SET 작업에 의해 제거됩니다. (1 행 영향) – pjp

0

나는이 (가) 외부 왼쪽 및 추가에 내부에서 가입 변경 판매가없는 지점의 ISNULL 기능.

SELECT 

    b.BranchName, 
    s.Month, 
    SUM(ISNULL(s.InvoiceAmount,0)) AS 'Sales' 
FROM 
    Branch b 
LEFT JOIN 
    Sales s ON s.BranchID = b.BranchID 
WHERE 
    s.Year = 2008 
AND 
    s.SalesRepID= 11 
GROUP BY 
    s.Month, 
    b.BranchName 
ORDER BY 
    s.Month, 
    b.BranchName 
+0

특정 달에 판매가 없더라도 월별 판매를 묻는 질문입니다. 이 쿼리는 전체 연도의 결과를 반환합니다. – pjp

+0

이것은 내 결과를 변경하지 않았습니다. – staterium

0

당신은 왼쪽 조인을 사용해야하고 ISNULL 바로 합계를 얻을 :

SELECT b.BranchName 
, SUM(isnull(s.InvoiceAmount, 0)) AS 'Sales' 
FROM  Branch b 
LEFT JOIN Sales s ON s.BranchID = b.BranchID 
GROUP BY  s.Month, b.BranchName 
ORDER BY  s.Month, b.BranchName 

당신은 여전히 ​​세일즈맨이있는 경우 달이 너무 보여주는 얻을 그것으로 좀 더 작업을 할 필요가 특정 달에 판매하지 않습니다.