이것은 전형적인 피벗 변환이며 Phil이 제안한 조건부 집계 는이를 구현하는 좋은 방법입니다.
PIVOT 절을 사용하는 동일한 결과를 얻는 더 현대적인 구문도 있습니다.
SELECT
CompanyName,
TotalOpenClaims = [1],
TotalClosedClaims = [2],
TotalReOpenedClaims = [3],
TotalPendingClaims = [4]
FROM
dbo.Claims
PIVOT
(
COUNT(ClaimID)
FOR StatusID IN ([1], [2], [3], [4])
) AS p
;
내부적으로는 이보다 간단하게 보이는 구문은 Phil의 GROUP BY 쿼리와 동일합니다. 보다 정확하게는 다음 변형과 같습니다.
SELECT
CompanyName,
TotalOpenClaims = COUNT(CASE WHEN StatusID = 1 THEN ClaimID END),
TotalClosedClaims = COUNT(CASE WHEN StatusID = 2 THEN ClaimID END),
TotalReOpenedClaims = COUNT(CASE WHEN StatusID = 3 THEN ClaimID END),
TotalPendingClaims = COUNT(CASE WHEN StatusID = 4 THEN ClaimID END)
FROM
dbo.Claims
GROUP BY
CompanyName
;
따라서 PIVOT 쿼리는 본질적으로 암시적인 GROUP BY 쿼리입니다.
그러나 PIVOT 쿼리는 조건부 집계를 사용하는 명시 적 GROUP BY 쿼리보다 처리하기가 까다 롭습니다. PIVOT을 사용할 때는 항상 다음 사항을 명심해야합니다.
Claims
PIVOT 절에서 명시 적으로 언급되지 않은 피벗 된 ( 이 경우) 데이터 세트의 모든 열 은 GROUP BY 열 입니다.
Claims
예제에 표시된 세 개의 열로만 구성된 경우 위의 PIVOT 쿼리는 예상대로 작동합니다. PIVOT CompanyName
에서 명시 적으로 언급되지 않은 유일한 열이므로 암시 적 GROUP BY의 유일한 기준으로 끝납니다.
그러나 Claims
다른 열 (예 ClaimDate
:)이 있으면 암시 적으로 추가 GROUP BY 열로 사용됩니다. 즉, 쿼리는 기본적으로 수행됩니다.
GROUP BY CompanyName, ClaimDate, ... /* whatever other columns there are*/`
결과는 아마도 원하는 것이 아닐 것입니다.
그래도 쉽게 고칠 수 있습니다. 관련이없는 열이 암시 적 그룹화에 참여하지 못하도록하려면 파생 테이블을 사용하면 결과에 필요한 열만 선택할 수 있지만 쿼리의 모양이 덜 우아해집니다.
SELECT
CompanyName,
TotalOpenClaims = [1],
TotalClosedClaims = [2],
TotalReOpenedClaims = [3],
TotalPendingClaims = [4]
FROM
(SELECT ClaimID, CompanyName, StatusID FROM dbo.Claims) AS derived
PIVOT
(
COUNT(ClaimID)
FOR StatusID IN ([1], [2], [3], [4])
) AS p
;
여전히 Claims
파생 테이블 인 경우 다른 수준의 중첩을 추가 할 필요가 없습니다. 현재 파생 테이블에서 출력을 생성하는 데 필요한 열만 선택해야합니다.
매뉴얼에서 PIVOT에 대한 자세한 내용을 읽을 수 있습니다.