UNPIVOT sütunları satırlara çevirir. Süreçte NULL değerleri ortadan kaldırır ( başvuru ) .
Girdi verildi
create table #t
(
ID int primary key,
c1 int null,
c2 int null
);
insert #t(id, c1, c2)
values
(1, 12, 13),
(2, null, 14),
(3, 15, null),
(4, null, null);
UNPIVOT sorgusu
select
ID, ColName, ColValue
from
(
select *
from #t
) as p
unpivot
(
ColValue for ColName in
(c1, c2) -- explicit source column names required
) as unpvt;
çıktı üretecek
| ID | ColName | ColValue |
|----|---------|----------|
| 1 | c1 | 12 |
| 1 | c2 | 13 |
| 2 | c2 | 14 |
| 3 | c1 | 15 |
Ne yazık ki 4. sıra sadece NULLs olduğu için tamamen elendi! Kaynak sorguya bir kukla değer enjekte ederek uygun şekilde yeniden eklenebilir:
select
ID, ColName, ColValue
from
(
select
-5 as dummy, -- injected here, -5 is arbitrary
*
from #t
) as p
unpivot
(
ColValue for ColName in
(dummy, c1, c2) -- referenced here
) as unpvt;
Kimlik üzerindeki satırları toplayarak null olmayan değerleri sayabiliriz. Kaynak tablodaki toplam sütun sayısıyla karşılaştırma, bir veya daha fazla NULL içeren satırları tanımlar.
select
ID
from
(
select -5 as dummy, *
from #t
) as p
unpivot
(
ColValue for ColName in
(dummy, c1, c2)
) as unpvt
group by ID
having COUNT(*) <> 3;
Enjekte edilen kukla sütun için
kaynak tablo #t
+ 1
- UNPIVOTED olmayan kimlik için 1 - sütun sayısını 3 olarak hesaplıyorum
Bu değer, çalışma zamanında katalog tabloları incelenerek elde edilebilir.
Orijinal satırlar, sonuçlara katılarak alınabilir.
NULL dışındaki değerler araştırılacaksa, bu değerler bir where yan tümcesine dahil edilebilir:
...
) as unpvt
where ColValue <> '' -- will eliminate empty strings
Tartışma
Bu, UNPIVOT üzerinden taşınan bir tanımlayıcı gerektirir. Bir anahtar en iyisi olurdu. Hiçbiri yoksa, ROW_NUMBER () pencere işlevi tarafından enjekte edilebilir , ancak bunun yürütülmesi pahalı olabilir.
Tüm sütunlar açıkça UNPIVOT yan tümcesinde listelenmelidir. @ Db2'nin önerdiği gibi SSMS kullanılarak sürüklenebilirler. Aaron Bertrand'ın önerisi gibi, tablo tanımı tarandığında dinamik olmayacaktır. Bununla birlikte, hemen hemen tüm SQL'ler için durum böyledir.
Oldukça sınırlı veri setim için yürütme planı, kümelenmiş bir dizin taraması ve bir akış toplamıdır. Bu, tablonun düz bir taramasından ve birçok OR yan tümcesinden daha pahalı bir bellek olacaktır.