Menghitung nilai nol dan bukan nol dalam satu kueri

141

Saya punya meja

create table us
(
 a number
);

Sekarang saya punya data seperti:

a
1
2
3
4
null
null
null
8
9

Sekarang saya perlu satu permintaan untuk menghitung nilai nol dan bukan nol di kolom a

Eric
sumber
3
Hai, di mana Anda perlu menghitung kode basis data semacam ini di basis data bahasa apa yang kita bicarakan Salam, Iordan
IordanTanev
2
Saya terkejut tidak ada jawaban tunggal berisi persatuan pilih sederhana (*) ...
Lieven Keersmaekers
1
@ Lieven: Kenapa kamu mau menggunakan di unionsini? Jawaban Montecristo sejauh ini merupakan solusi terbaik.
Eric
1
Karena OP menginginkannya dengan satu permintaan. Jawaban Montecristo memang sejauh ini merupakan solusi terbaik ... dia hanya perlu menambahkan serikat :)
Lieven Keersmaekers
1
Dan itulah yang saya dapatkan ketika membaca judulnya. Akan diedit.
Eric

Jawaban:

231

Ini berfungsi untuk Oracle dan SQL Server (Anda mungkin bisa membuatnya bekerja di RDBMS lain):

select sum(case when a is null then 1 else 0 end) count_nulls
     , count(a) count_not_nulls 
  from us;

Atau:

select count(*) - count(a), count(a) from us;
Rodrigue
sumber
1
Menggunakan perbedaan antara count(*)dan count(a)juga bekerja dengan baikgroup by
shannon
1
@shannon Saya setuju, COUNT(a)adalah komentar yang berguna untuk ditambahkan, tetapi ini tidak memberikan peringatan / kesalahan tergantung pada tumpukan Anda dan mungkin memerlukan komentar dalam kode. Saya lebih suka SUMmetodenya.
Richard
4
Lebih count(*)kecount(1)
Lei Zhao
61

Jika saya mengerti dengan benar Anda ingin menghitung semua NULL dan semua TIDAK NULL dalam kolom ...

Jika itu benar:

SELECT count(*) FROM us WHERE a IS NULL 
UNION ALL
SELECT count(*) FROM us WHERE a IS NOT NULL

Diedit untuk memiliki kueri lengkap, setelah membaca komentar:]


SELECT COUNT(*), 'null_tally' AS narrative 
  FROM us 
 WHERE a IS NULL 
UNION
SELECT COUNT(*), 'not_null_tally' AS narrative 
  FROM us 
 WHERE a IS NOT NULL;
Alberto Zaccagni
sumber
7
+1: Sejauh ini cara termudah dan tercepat. Saya terkejut ketika setiap jawaban bukan ini.
Eric
6
Ya tapi tidak Saya pikir dia ingin memiliki jumlah NULL dan tidak NULL hanya satu query ... Anda mengatakan bagaimana melakukan itu dalam dua pertanyaan ...
Romain Linsolas
@romaintaz: Benar sekali. Saya membaca judulnya sebagai pertanyaan. Dalam lima suntingan, tidak ada yang berpikir untuk memperbaikinya. Ya.
Eric
@romaintaz: Ya Anda benar, saya menganggap ini sebagai "jalankan permintaan sekali lagi untuk mengetahui berapa banyak nol yang kami miliki", saya bahkan tidak tahu mengapa ^^ ', akan diperbaiki, terima kasih.
Alberto Zaccagni
1
@Montecristo: Karena judul meminta hanya menghitung null:)
Eric
42

Ini adalah versi cepat dan kotor yang berfungsi pada Oracle:

select sum(case a when null then 1 else 0) "Null values",
       sum(case a when null then 0 else 1) "Non-null values"
from us
christopheml
sumber
3
Sintaks yang sama akan bekerja di SQL Server juga. Juga, melakukannya dengan cara ini hanya akan memindai tabel sekali; solusi UNION akan melakukan dua pemindaian tabel. Tidak relevan untuk meja kecil, sangat penting untuk meja besar.
Philip Kelley
2
Hanya perubahan untuk SQL Server "Null values"harus menjadi 'Null values'. Kutipan tunggal, bukan ganda.
Eric
1
SQLServer menggunakan pemindaian indeks untuk kueri ini vs dua indeks yang berusaha menggunakan gabungan. Di atas meja dengan 40.000 baris, tidak ada perbedaan kecepatan.
Lieven Keersmaekers
1
Di atas meja dengan 11.332.581 baris, ada dua pemindaian tabel , tidak ada perbedaan kecepatan yang nyata (sebenarnya, penyatuan sedikit lebih cepat).
Lieven Keersmaekers
1
Ini tidak berhasil untuk saya di Oracle 11g. Versi @ user155789 diposting dengan "case ketika a adalah null maka 1 else 0 end" adalah sintaks yang bekerja.
Steve
25

Saat saya memahami permintaan Anda, Anda cukup menjalankan skrip ini dan mendapatkan Total Null, Total NotNull rows,

select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us;
Ariful Haque
sumber
23

untuk yang bukan nol

select count(a)
from us

untuk nulls

select count(*)
from us

minus 

select count(a)
from us

Karenanya

SELECT COUNT(A) NOT_NULLS
FROM US

UNION

SELECT COUNT(*) - COUNT(A) NULLS
FROM US

seharusnya melakukan pekerjaan itu

Lebih baik dalam hal judul kolom yang keluar benar.

SELECT COUNT(A) NOT_NULL, COUNT(*) - COUNT(A) NULLS
FROM US

Dalam beberapa pengujian pada sistem saya, perlu pemindaian tabel penuh.

EvilTeach
sumber
4
Saus yang bagus, teman, lihat rencana eksekusi untuk pertanyaan ini. Anda memulai pemindaian tabel ke kiri dan ke kanan, terutama di mana ada pernyataan sederhana berdarah ( select count(*) from t where a is null) yang melakukan ini.
Eric
2
Saya tidak memiliki database yang mudah dilihat, tetapi kolomnya diindeks atau tidak. Jika ya, itu terjadi melalui pemindaian rentang, jika tidak, Anda cukup banyak dengan pemindaian tabel penuh. Di oracle, NULLs tidak disimpan dalam indeks, jadi saya curiga contoh Anda tidak jauh lebih baik. Jarak Anda mungkin sangat.
EvilTeach
1
@EvilTeach: Indeks hanya membantu ketika Anda tidak menarik kembali> ~ 10% dari baris. Setelah itu, pemindaian penuh dimulai. Dalam hal ini, Anda akan mendapatkan pemindaian setidaknya sekali, jika tidak dua kali.
Eric
19

biasanya saya menggunakan trik ini

select sum(case when a is null then 0 else 1 end) as count_notnull,
       sum(case when a is null then 1 else 0 end) as count_null
from tab
group by a
elle0087
sumber
6

Ini sedikit rumit. Asumsikan tabel hanya memiliki satu kolom, maka Hitung (1) dan Hitung (*) akan memberikan nilai yang berbeda.

set nocount on
    declare @table1 table (empid int)
    insert @table1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(NULL),(11),(12),(NULL),(13),(14);

    select * from @table1
    select COUNT(1) as "COUNT(1)" from @table1
    select COUNT(empid) "Count(empid)" from @table1

Hasil Permintaan

Seperti yang Anda lihat pada gambar, Hasil pertama menunjukkan tabel memiliki 16 baris. dari mana dua baris NULL. Jadi ketika kita menggunakan Hitung (*) mesin kueri menghitung jumlah baris, Jadi kita mendapat hasil hitung sebagai 16. Tapi dalam kasus Hitung (empid) itu menghitung nilai-nilai NULL-NULL dalam kolom empid . Jadi kami mendapat hasilnya 14.

jadi setiap kali kita menggunakan COUNT (Kolom) pastikan kita menjaga nilai NULL seperti yang ditunjukkan di bawah ini.

select COUNT(isnull(empid,1)) from @table1

akan menghitung nilai NULL dan Non-NULL.

Catatan : Hal yang sama berlaku bahkan ketika tabel terdiri dari lebih dari satu kolom. Hitung (1) akan memberikan jumlah total baris terlepas dari nilai NULL / Non-NULL. Hanya ketika nilai kolom dihitung menggunakan Count (Kolom) kita perlu menjaga nilai NULL.

Santhoshkumar LM
sumber
4

Saya memiliki masalah serupa: untuk menghitung semua nilai yang berbeda, menghitung nilai nol sebagai 1 juga. Hitungan sederhana tidak berfungsi dalam kasus ini, karena tidak memperhitungkan nilai nol.

Berikut cuplikan yang berfungsi pada SQL dan tidak melibatkan pemilihan nilai baru. Pada dasarnya, setelah melakukan yang berbeda, juga mengembalikan nomor baris dalam kolom baru (n) menggunakan fungsi row_number (), kemudian melakukan penghitungan pada kolom itu:

SELECT COUNT(n)
FROM (
    SELECT *, row_number() OVER (ORDER BY [MyColumn] ASC) n
    FROM (
        SELECT DISTINCT [MyColumn]
                    FROM [MyTable]
        ) items  
) distinctItems
Starnuto di topo
sumber
3

Berikut adalah dua solusi:

Select count(columnname) as countofNotNulls, count(isnull(columnname,1))-count(columnname) AS Countofnulls from table name

ATAU

Select count(columnname) as countofNotNulls, count(*)-count(columnname) AS Countofnulls from table name
Amal Hari
sumber
3

Mencoba

SELECT 
   SUM(ISNULL(a)) AS all_null,
   SUM(!ISNULL(a)) AS all_not_null
FROM us;

Sederhana!

Rodrigo Prazim
sumber
3

Coba ini..

SELECT CASE 
         WHEN a IS NULL THEN 'Null' 
         ELSE 'Not Null' 
       END a, 
       Count(1) 
FROM   us 
GROUP  BY CASE 
            WHEN a IS NULL THEN 'Null' 
            ELSE 'Not Null' 
          END 
Ayush Raj
sumber
2

Jika Anda menggunakan MS Sql Server ...

SELECT COUNT(0) AS 'Null_ColumnA_Records',
(
    SELECT COUNT(0)
    FROM your_table
    WHERE ColumnA IS NOT NULL
) AS 'NOT_Null_ColumnA_Records'
FROM your_table
WHERE ColumnA IS NULL;

Saya tidak merekomendasikan Anda melakukan ini ... tetapi di sini Anda memilikinya (dalam tabel yang sama sebagai hasilnya)

Andrei
sumber
2

gunakan fungsi tertanam ISNULL.


Sajikan
sumber
Ini juga jawaban yang layak. Saya pribadi menemukan bahwa COUNT (DISTINCT ISNULL (A, '')) bekerja lebih baik daripada COUNT (DISTINCT A) + SUM (KASUS SAAT NULL KEMUDIAN 1 LAIN 0 SELESAI)
Vladislav
1

jika ini mysql, Anda dapat mencoba sesuatu seperti ini.

select 
   (select count(*) from TABLENAME WHERE a = 'null') as total_null, 
   (select count(*) from TABLENAME WHERE a != 'null') as total_not_null
FROM TABLENAME
TigerTiger
sumber
1
SELECT SUM(NULLs) AS 'NULLS', SUM(NOTNULLs) AS 'NOTNULLs' FROM 
    (select count(*) AS 'NULLs', 0 as 'NOTNULLs' FROM us WHERE a is null
    UNION select 0 as 'NULLs', count(*) AS 'NOTNULLs' FROM us WHERE a is not null) AS x

Ini jelek, tetapi itu akan mengembalikan satu catatan dengan 2 cols menunjukkan jumlah nol vs bukan nol.

C-Pound Guru
sumber
1

Ini bekerja di T-SQL. Jika Anda hanya menghitung jumlah sesuatu dan Anda ingin memasukkan nol, gunakan COALESCE sebagai ganti case.

IF OBJECT_ID('tempdb..#us') IS NOT NULL
    DROP TABLE #us

CREATE TABLE #us
    (
    a INT NULL
    );

INSERT INTO #us VALUES (1),(2),(3),(4),(NULL),(NULL),(NULL),(8),(9)

SELECT * FROM #us

SELECT CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END AS 'NULL?',
        COUNT(CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END) AS 'Count'
    FROM #us
    GROUP BY CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END

SELECT COALESCE(CAST(a AS NVARCHAR),'NULL') AS a,
        COUNT(COALESCE(CAST(a AS NVARCHAR),'NULL')) AS 'Count'
    FROM #us
    GROUP BY COALESCE(CAST(a AS NVARCHAR),'NULL')
DaveX
sumber
1

Membangun Alberto, saya menambahkan rollup.

 SELECT [Narrative] = CASE 
 WHEN [Narrative] IS NULL THEN 'count_total' ELSE    [Narrative] END
,[Count]=SUM([Count]) FROM (SELECT COUNT(*) [Count], 'count_nulls' AS [Narrative]  
FROM [CrmDW].[CRM].[User]  
WHERE [EmployeeID] IS NULL 
UNION
SELECT COUNT(*), 'count_not_nulls ' AS narrative 
FROM [CrmDW].[CRM].[User] 
WHERE [EmployeeID] IS NOT NULL) S 
GROUP BY [Narrative] WITH CUBE;
Brian Connelly
sumber
1
SELECT
    ALL_VALUES
    ,COUNT(ALL_VALUES)
FROM(
        SELECT 
        NVL2(A,'NOT NULL','NULL') AS ALL_VALUES 
        ,NVL(A,0)
        FROM US
)
GROUP BY ALL_VALUES
Istiaque Hossain
sumber
1
select count(isnull(NullableColumn,-1))
Imran Shamszadeh
sumber
2
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan meningkatkan nilai jangka panjangnya.
Vishal Chhodwani
1

Semua jawaban salah atau sangat kedaluwarsa.

Cara sederhana dan benar untuk melakukan kueri ini menggunakan COUNT_IFfungsi.

SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us
Martín Fixman
sumber
0

Untuk berjaga-jaga jika Anda menginginkannya dalam satu catatan:

select 
  (select count(*) from tbl where colName is null) Nulls,
  (select count(*) from tbl where colName is not null) NonNulls 

;-)

Sparhawk_
sumber
0

untuk menghitung bukan nilai nol

select count(*) from us where a is not null;

untuk menghitung nilai nol

 select count(*) from us where a is null;
Shah yang dalam
sumber
1
Op meminta permintaan tunggal :)
infografnet
0

Saya membuat tabel di postgres 10 dan kedua hal berikut ini berfungsi:

select count(*) from us

dan

select count(a is null) from us

skrillybrick
sumber
a IS NULLmenghasilkan TRUEatau FALSE, dan COUNT () akan menghitung semua nilai NOT NULL. Jadi count(a is null)akan mengembalikan jumlah semua baris.
ypresto
0

Dalam kasus saya, saya ingin " distribusi nol " di antara banyak kolom:

SELECT
       (CASE WHEN a IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS a_null,
       (CASE WHEN b IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS b_null,
       (CASE WHEN c IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS c_null,
       ...
       count(*)
FROM us
GROUP BY 1, 2, 3,...
ORDER BY 1, 2, 3,...

Sesuai '...' dapat dengan mudah diperluas ke lebih banyak kolom, sebanyak yang dibutuhkan

Vzzarr
sumber
-1

Jumlah elemen di mana a adalah null:

select count(a) from us where a is null;

Jumlah elemen di mana a bukan nol:

select count(a) from us where a is not null;
Romain Linsolas
sumber
1
Pertanyaannya adalah untuk satu permintaan.
DreamWave