it-swarm.asia

Uji apakah ada kolom NULL

Saya mencoba mencari tahu kueri mudah yang bisa saya lakukan untuk menguji apakah tabel besar memiliki daftar entri yang memiliki setidaknya SATU nilai kosong (NULL/kosong) di kolom APA PUN.

Saya butuh sesuatu seperti

SELECT * FROM table AS t WHERE ANY(t.* IS NULL)

Saya tidak mau harus melakukan

SELECT * FROM table AS t WHERE t.c1 = NULL OR t.c2 = NULL OR t.c3 = NULL

Ini akan menjadi permintaan BESAR.

16
Dexter

Ekstensi ke jawaban @ db2 dengan sedikit (baca: nol) perselisihan dengan tangan:

DECLARE @tb nvarchar(512) = N'dbo.[table]';

DECLARE @sql nvarchar(max) = N'SELECT * FROM ' + @tb
    + ' WHERE 1 = 0';

SELECT @sql += N' OR ' + QUOTENAME(name) + ' IS NULL'
    FROM sys.columns 
    WHERE [object_id] = OBJECT_ID(@tb);

EXEC sys.sp_executesql @sql;
16
Aaron Bertrand

Anda harus mencantumkan semua kolom sesuai komentar JNK.

WHERE c1 IS NULL OR c2 IS NULL OR c3 IS NULL

Pendekatan yang agak kurang efisien yang menghindari ini ada di bawah ini.

;WITH xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' AS ns) 
SELECT * 
FROM   YourTable AS T1 
WHERE (
    SELECT T1.* 
    FOR XML PATH('row'), ELEMENTS XSINIL, TYPE
  ).exist('//*/@ns:nil') = 1 

(Berdasarkan ini SO jawaban)

8
Martin Smith

Tidak ada sintaks bawaan yang bagus, tetapi Management Studio memiliki beberapa fitur yang nyaman untuk menghasilkan kueri dengan cepat.

Di Object Explorer, telusuri tabel yang Anda inginkan, perluas, lalu seret seluruh folder "Kolom" ke dalam editor kueri kosong. Ini akan menambahkan daftar kolom yang dipisahkan koma ke kueri.

Selanjutnya, buka Temukan Dan Ganti. Setel "Temukan Apa" menjadi , dan atur "Ganti Dengan" menjadi IS NULL OR (dengan spasi di depan) lalu tekan Ganti Semua. Anda harus membersihkan yang terakhir secara berurutan dengan tangan.

Masih jelek, tapi kurang padat karya.

5
db2

Beberapa Solusi untuk: beberapa nol, semua nol, satu & beberapa kolom ditambah menjadikannya CEPAT menggunakan Top 1

Jika Anda perlu menguji beberapa kolom, Anda dapat menggunakan yang berikut:

Column_1 Column_2 Column_3
-------- -------- --------
1        2        NULL
1        NULL     NULL
5        6        NULL

Pertama, uji NULL dan hitung:

select 
    sum(case when Column_1 is null then 1 else 0 end) as Column_1, 
    sum(case when Column_2 is null then 1 else 0 end) as Column_2, 
    sum(case when Column_3 is null then 1 else 0 end) as Column_3,
from TestTable 

Menghasilkan hitungan NULLs:

Column_1  Column_2  Column_3
0         1         3

Di mana hasilnya adalah 0, tidak ada NULL.

Kedua, mari kita hitung non-NULL:

select 
    sum(case when Column_1 is null then 0 else 1 end) as Column_1, 
    sum(case when Column_2 is null then 0 else 1 end) as Column_2, 
    sum(case when Column_3 is null then 0 else 1 end) as Column_3,
from TestTable

... Tetapi karena kami menghitung non-NULL di sini, ini dapat disederhanakan menjadi:

select 
    count(Column_1) as Column_1, 
    count(Column_2) as Column_2, 
    count(Column_3) as Column_3,
from TestTable

Salah satu hasil:

Column_1  Column_2  Column_3
3         2         0

Di mana hasilnya adalah 0, kolom seluruhnya terdiri dari NULLs.

Terakhir, jika Anda hanya perlu memeriksa kolom tertentu, maka TOP 1 lebih cepat karena harus berhenti pada klik pertama. Anda kemudian dapat secara opsional menggunakan count (*) untuk memberikan hasil gaya boolean:

select top 1 'There is at least one NULL' from TestTable where Column_3 is NULL

select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a

0 = Tidak ada NULL, 1 = Setidaknya ada satu NULL

atau

select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL

select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a

0 = Semuanya NULL, 1 = Setidaknya ada satu NULL

Saya harap ini membantu.

4
jwolf

UNPIVOT menerjemahkan kolom menjadi baris. Dalam prosesnya menghilangkan nilai NULL ( referensi ).

Diberikan input

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);

permintaan UNPIVOT

select
    ID, ColName, ColValue
from
(
    select *
    from #t
) as p
unpivot
(
    ColValue for ColName in
    (c1, c2)                  -- explicit source column names required
) as unpvt;

akan menghasilkan output

| ID | ColName | ColValue |
|----|---------|----------|
| 1  | c1      | 12       |
| 1  | c2      | 13       |
| 2  | c2      | 14       |
| 3  | c1      | 15       |

Sayangnya baris 4 telah dihilangkan seluruhnya karena hanya memiliki NULL! Itu dapat dengan mudah diperkenalkan kembali dengan menyuntikkan nilai dummy ke dalam kueri sumber:

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;

Dengan menjumlahkan baris pada ID kita dapat menghitung nilai-nilai yang bukan nol. Perbandingan dengan jumlah total kolom dalam tabel sumber akan mengidentifikasi baris yang berisi satu atau lebih NULL.

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;

Saya menghitung 3 sebagai
jumlah kolom dalam tabel sumber #t
+1 untuk kolom boneka yang disuntikkan
- 1 untuk ID, yang tidak UNPIVOTED

Nilai ini dapat diperoleh saat runtime dengan memeriksa tabel katalog.

Baris asli dapat diambil dengan bergabung ke hasilnya.

Jika nilai selain NULL harus diselidiki, nilai itu dapat dimasukkan dalam klausa where:

...
) as unpvt
where ColValue <> ''      -- will eliminate empty strings

Diskusi

Ini membutuhkan pengenal yang dilakukan melalui UNPIVOT. Kunci akan menjadi yang terbaik. Jika tidak ada, dapat disuntikkan oleh fungsi jendela ROW_NUMBER () , meskipun ini mungkin mahal untuk dieksekusi.

Semua kolom harus dicantumkan secara eksplisit di dalam klausa UNPIVOT. Mereka dapat diseret menggunakan SSMS, seperti yang disarankan @ db2. Itu tidak akan dinamis ketika definisi tabel chagnes, seperti saran Aaron Bertrand. Ini adalah kasus untuk hampir semua SQL.

Untuk set data yang agak terbatas, rencana eksekusi adalah pemindaian indeks berkerumun dan agregat aliran. Memori ini akan lebih mahal daripada pemindaian langsung tabel dan banyak klausa OR.

2
Michael Green