2016-12-04 56 views
7

Bir satırda NULL değerlerinin sayısını saymak istiyorum. ÖrneğinBir satırdaki NULL değerler sayısını sayın

:

Name Col1 Col2  Col3  Col4 | ansCol 
abc  null [email protected] null  null | 3 
bbc  null null  null  null | 4 

Bu örnekte Cevap basit: Biz çok geniş bir tablo, 10'dan fazla sütun varsa

SELECT *, 
(CASE WHEN Name IS NULL THEN 1 ELSE 0 END + 
CASE WHEN Col1 IS NULL THEN 1 ELSE 0 END +  
CASE WHEN Col2 IS NULL THEN 1 ELSE 0 END +  
CASE WHEN Col3 IS NULL THEN 1 ELSE 0 END +  
CASE WHEN Col4 IS NULL THEN 1 ELSE 0 END) as ansCol 

soru daha karmaşık hale gelir.

Msg 125, Level 15, State 4, Line 13 Case expressions may only be nested to level 10.

bu üstesinden gelmek için bir yol var mı: Ben şu hatayı alıyorum gösterildi yöntemini kullanmaya çalışırsanız?

+0

13 sütun için Case kullanıyorum ve sorun yok mu? Yanlış bir şey mi yaptım? –

+0

@ahmedabdelqader Lütfen herkesin cevabı altında değil, soru altında böyle bir yorum bırakın. –

+0

@TimBiegeleisen Yapıldı. –

cevap

1

Yukarıdakilere ek olarak, potansiyel bir yaklaşım, PIVOT ve UNPIVOT özelliğe kullanmak olacaktır.

Let ilk tablo oluşturmak ve söz başı verileri ekleyin:

Öncelikle yapmamız kimlik masayı benzersiz olarak verileri veri her satırı tanımlamak ve yerleştirmek, böylece bu şekilde oluşturmaktır ne olacak
/* Create table */ 
CREATE TABLE so_40957006 (
    [name] VARCHAR(24), 
    [col1] VARCHAR(24), 
    [col2] VARCHAR(24), 
    [col3] VARCHAR(24), 
    [col4] VARCHAR(24) 
) 

/* Insert data */ 
INSERT INTO so_40957006 VALUES('abc', null, '[email protected]', null, null) 
INSERT INTO so_40957006 VALUES('bbc', null, null, null, null) 

. Bu süreç içinde IsNull kullanılarak 1 değerine null sütunların herhangi dönüştürdüğümüzü

/* Create identity table */ 
CREATE TABLE so_40957006_id (
    [lid] INT IDENTITY(1, 1), 
    [name] VARCHAR(24), 
    [col1] VARCHAR(24), 
    [col2] VARCHAR(24), 
    [col3] VARCHAR(24), 
    [col4] VARCHAR(24) 
) 

/* Insert data into table */ 
INSERT INTO so_40957006_id 
SELECT 
    ISNULL([name], 1) AS [name] 
,ISNULL([col1], 1) AS [col1] 
,ISNULL([col2], 1) AS [col2] 
,ISNULL([col3], 1) AS [col3] 
,ISNULL([col4], 1) AS [col4] 
FROM so_40957006 

not edin. Tablo şimdi aşağıdakine benziyor. Bununla

lid name col1 col2 col3 col4 
1 abc  1  [email protected] 1  1 
2 bbc  1  1  1  1 

, şimdi dikey olarak hareket verilerine PIVOT ve UNPIVOT kullanabilirsiniz. Örneğin,

SELECT [lid], [cols], [val] 
FROM 
    (SELECT [lid], [name], [col1], [col2], [col3], [col4] 
     FROM so_40957006_id) p 
UNPIVOT 
    (val FOR cols IN 
    ([name], [col1], [col2], [col3], [col4]) 
) AS unpvt 

aşağıdaki sorgu çalışan dikey çıkış sağlar: saymak istediğiniz değerleri yana

lid cols val 
1 name abc 
1 col1 1 
1 col2 [email protected] 
1 col3 1 
1 col4 1 
2 name bbc 
2 col1 1 
2 col2 1 
2 col3 1 
2 col4 1 

(yaniOrijinal tabloya geri [lid] yapabilirsiniz JOIN bu çıkışı ile çıktı

lid CountNulls 
1 3 
2 4 

ile

SELECT [lid], SUM(cast([val] as integer)) as CountNulls 
    FROM (
    SELECT [lid], [cols], [val] 
    FROM 
     (SELECT [lid], [name], [col1], [col2], [col3], [col4] 
      FROM so_40957006_id) p 
    UNPIVOT 
    (val FOR cols IN 
     ([name], [col1], [col2], [col3], [col4]) 
    ) AS unpvt 
) a 
WHERE ISNUMERIC([val]) = 1 
GROUP BY [lid] 

: NULL ler) 1 değeri, sadece bir GROUP BY + SUM deyimi çalıştırabilirsiniz var sonuç kümenizi oluşturmak için

1

Bu, bir kesmek gibi görünüyor ve belki de tasarımınızı değiştirmeli veya tablonuzdaki sütun sayısını azaltmalısınız, ancak bunu yapmanız gerekiyorsa, 10 sütun iç içe sınırını aşmak için bir alt sorgunun kullanılması gerekir: Eğer sadece iyi eklenmesiyle zinciri birlikte 10'dan fazla mümkün olmalıdır böylece

SELECT t.*, 
     t.firstBatch + t.secondBatch AS ansCol 
FROM 
(
    SELECT *, 
     (CASE WHEN Col1 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN Col2 IS NULL THEN 1 ELSE 0 END +  
     ... 
     CASE WHEN Col10 IS NULL THEN 1 ELSE 0 END) AS firstBatch, 
     (CASE WHEN Col11 IS NULL THEN 1 ELSE 0 END + 
     CASE WHEN Col12 IS NULL THEN 1 ELSE 0 END +  
     ... 
     CASE WHEN Col20 IS NULL THEN 1 ELSE 0 END) AS secondBatch 
    FROM yourTable 
) t 
5

sorunuzu kodu herhangi iç içe durum yoktur.

Ama diğer bazı olasılıklar vardır ... tüm sütunlar aynı veri türü varsa

aynı olması onlara güvenmez ( Demo)

SELECT *, 
     ansCol = (SELECT COUNT(*) - COUNT(C) FROM (VALUES(c1),(c2),(c3),(c4)) V(C)) 
FROM t1 

Veya başka bir alternatif kullanabilirsiniz veri tipi.

;WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' as ns) 
SELECT *, 
     ansCol = (SELECT x.* FOR XML PATH('row'), 
        ELEMENTS XSINIL, TYPE).value('count(/row/*[@ns:nil])', 'int') 
FROM t1 x 
+0

İkinci alternatif süper cool .. –

İlgili konular