Bu tipik bir pivot dönüşümüdür ve Phil tarafından önerildiği gibi koşullu toplama, bunu uygulamanın eski güzel yoludur.
Aynı sonucu elde etmek için PIVOT yan tümcesini kullanan daha modern bir sözdizimi de vardır:
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
;
Dahili olarak bu tartışmasız daha basit görünen sözdizimi Phil'in GROUP BY sorgusuna eşdeğerdir. Daha doğrusu, bu varyasyona eşdeğerdir:
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
;
Bu nedenle, bir PIVOT sorgusu esasen örtülü bir GROUP BY sorgusudur.
Bununla birlikte, PIVOT sorguları, koşullu toplama özelliğine sahip açık GROUP BY sorgularından çok daha karmaşıktır. PIVOT'u kullanırken, daima bu tek şeyi aklınızda bulundurmanız gerekir:
- Tüm sütunlar veri kümesinin (doğru açılmış
Claims
bu durumda) açıkça MİL maddede belirtilen olmadığını GRUBU TARAFINDAN sütunlar bulunmaktadır .
Eğer Claims
sizin örnekte görüldüğü yalnızca üç sütun oluşur çünkü görünüşte irade işin üstünde PIVOT sorgu, beklendiği gibi CompanyName
açıkça PIVOT söylenmeyen tek sütun ve dolayısıyla örtük GROUP BY tek kriter olarak sona erer.
Ancak, Claims
başka sütunlar (diyelim ki ClaimDate
) varsa, bunlar dolaylı olarak ek GROUP BY sütunları olarak kullanılacaktır - yani, sorgunuz esasen
GROUP BY CompanyName, ClaimDate, ... /* whatever other columns there are*/`
Sonuç büyük olasılıkla istediğiniz gibi olmayacaktır.
Ancak bunu düzeltmek kolaydır. Alakasız sütunların örtülü gruplamaya katılmasını engellemek için, yalnızca sonuç için gereken sütunları seçeceğiniz türetilmiş bir tablo kullanabilirsiniz; ancak bu, sorguyu daha zarif görünmesine neden olur:
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
;
Yine de, Claims
zaten türetilmiş bir tablo varsa, başka bir iç içe yerleştirme düzeyi eklemenize gerek yoktur, sadece mevcut türetilmiş tabloda yalnızca çıktıyı üretmek için gereken sütunları seçtiğinizden emin olun.
Kılavuzda PIVOT hakkında daha fazla bilgi edinebilirsiniz: