Bu, bir bakıma, Lennart'ın çözümünün bir uzantısıdır , ancak o kadar çirkin ki, bunu bir düzenleme olarak önermeye cesaret edemem. Buradaki amaç, sonuçları türetilmiş bir tablo olmadan elde etmektir. Buna asla ihtiyaç olmayabilir ve sorgunun çirkinliği ile birleşince tüm çaba boşa giden bir çaba gibi görünebilir. Yine de bunu bir egzersiz olarak yapmak istedim ve şimdi sonucumu paylaşmak istiyorum:
SELECT
Col_A,
Col_B,
DistinctCount = DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B ASC )
+ DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B DESC)
- 1
- CASE COUNT(Col_B) OVER (PARTITION BY Col_A)
WHEN COUNT( * ) OVER (PARTITION BY Col_A)
THEN 0
ELSE 1
END
FROM
dbo.MyTable
;
Hesaplamanın temel kısmı şudur (ve her şeyden önce fikrin benim olmadığını belirtmek isterim, bu numarayı başka bir yerde öğrendim):
DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B ASC )
+ DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B DESC)
- 1
Bu ifadenin, değerlerin Col_B
hiçbir zaman sıfır olmadığı garanti edilirse, herhangi bir değişiklik yapılmadan kullanılabilir . Sütunda null değerler varsa, bunu hesaba katmanız gerekir ve CASE
ifadenin tam olarak bunun için var olduğunu gösterir. O sayısı ile bölüm başına satır sayısını karşılaştırır Col_B
değerlerine bölüm başına. Sayılar farklıysa, bazı satırların boş olduğu anlamına gelir Col_B
ve bu nedenle ilk hesaplamanın ( DENSE_RANK() ... + DENSE_RANK() - 1
) 1 azaltılması gerekir.
Çünkü Not - 1
çekirdek formül parçasıdır, böyle bırakmak seçtik. Bununla birlikte, CASE
tüm çözümün daha az çirkin görünmesi için boşuna denemede aslında ifadeye dahil edilebilir :
SELECT
Col_A,
Col_B,
DistinctCount = DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B ASC )
+ DENSE_RANK() OVER (PARTITION BY Col_A ORDER BY Col_B DESC)
- CASE COUNT(Col_B) OVER (PARTITION BY Col_A)
WHEN COUNT( * ) OVER (PARTITION BY Col_A)
THEN 1
ELSE 2
END
FROM
dbo.MyTable
;
Db <> fiddle.uk adresindeki bu canlı demo , çözümün her iki varyasyonunu test etmek için kullanılabilir.