Tek bir sorguda null ve null olmayan değerleri sayma


141

Masam var

create table us
(
 a number
);

Şimdi şöyle verilerim var:

a
1
2
3
4
null
null
null
8
9

Şimdi null adlı saymak için tek sorgu ihtiyaç ve sütun a değil boş değerler


3
Merhaba, Nerede hangi dil veritabanında sayıyoruz veritabanı kodu sayma bu tür gerekiyor En iyi Saygılarımızla, Iordan
IordanTanev

2
Tek bir cevap belirli bir sayı (*) basit bir birlik içermiyor şaşırdım ...
Lieven Keersmaekers

1
@Lieven: Neden unionburada bir yer kullanırsın ? Montecristo'nun cevabı açık ara en iyi çözümdür.
Eric

1
Çünkü OP tek bir sorgu ile istiyor. Montecristo'nun cevabı gerçekten de en iyi çözüm ... sadece birliği eklemesi gerekiyor :)
Lieven Keersmaekers

1
Ve başlığı okumak için aldığım şey bu. Düzenleyecek.
Eric

Yanıtlar:


231

Bu Oracle ve SQL Server için çalışır (başka bir RDBMS üzerinde çalışmasını sağlayabilirsiniz):

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

Veya:

select count(*) - count(a), count(a) from us;

1
Arasındaki farkı kullanmak count(*)ve count(a)aynı zamanda iyi çalışırgroup by
shannon

1
@shannon Kabul ediyorum, COUNT(a)eklemek için yararlı bir yorum, ancak bu, yığınıza bağlı olarak bir uyarı / hata atıyor ve kodda bir yorum gerektirebilir. SUMYöntemi tercih ederim .
Richard

4
Tercih count(*)etmekcount(1)
Lei Zhao

61

Doğru anladıysam, bir sütundaki tüm NULL ve NULL DEĞİL saymak istiyorum ...

Bu doğruysa:

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

Yorumları okuduktan sonra tam sorguyu alacak şekilde düzenlendi:]


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;

7
+1: Şimdiye kadarki en basit, en hızlı yol. Her cevap bu olmadığında şok oldum.
Eric

6
Evet fakat hayır. Bence sadece tek bir sorguda NULL sayısı ve NULL değil ... Bunu iki sorguda nasıl yapacağınızı söylüyorsunuz ...
Romain Linsolas

@romaintaz: Çok doğru. Başlığı soru olarak okudum. Beş düzenlemede kimse bunu düzeltmeyi düşünmedi. Yeesh.
Eric

@romaintaz: Evet haklısın, bunu "kaç tane boş değerli olduğumuzu tespit etmek için bir kez çalıştır sorgusu" olarak aldım, neden düzeleceğimi bilmiyorum ^^ ', düzelteceğim, teşekkürler.
Alberto Zaccagni

1
@Montecristo: Çünkü başlık sadece saymak istedi null:)
Eric

42

İşte Oracle üzerinde çalışan hızlı ve kirli bir sürüm:

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

3
Benzer sözdizimi SQL Server'da da çalışır. Ayrıca, bu şekilde yapmak tabloyu yalnızca bir kez tarar; UNION çözümleri iki tablo taraması yapacak. Küçük masalar için alakasız, büyük masalar için çok önemlidir.
Philip Kelley

2
Sadece SQL Server için değişiklik "Null values"olması gerekir 'Null values'. Tek tırnak, iki katına değil.
Eric

1
SQLServer, bir birleşim kullanarak iki dizin aramaya karşı bu sorgu için bir dizin taraması kullanır . 40.000 sıralı bir tabloda hız farkı yoktur.
Lieven Keersmaekers

1
11.332.581 satır içeren bir tabloda, iki tablo taraması vardır , fark edilebilir hız farkı yoktur (aslında, birleşim biraz daha hızlıdır).
Lieven Keersmaekers

1
Oracle 11g'de bu benim için çalışmadı. @ User155789 sürümü "a null olduğunda 1 başka 0 son olduğunda case" ile çalışan sözdizimiydi.
Steve

25

Sorgunuzu anladığım gibi, sadece bu komut dosyasını çalıştırıp Total Null, Total NotNull satırları,

select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us;

23

boş olmayanlar için

select count(a)
from us

sıfırlar için

select count(*)
from us

minus 

select count(a)
from us

bundan dolayı

SELECT COUNT(A) NOT_NULLS
FROM US

UNION

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

işi yapmalı

Sütun başlıklarının doğru çıkması daha iyi.

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

Sistemimdeki bazı testlerde, tam bir masa taraması maliyeti.


4
İyi sos adamım, bu sorguların icra planlarına bakın. Masa taramalarını sola ve sağa vuruyorsunuz, özellikle de bunu yapan böyle kanlı basit bir ifade ( select count(*) from t where a is null) olduğunda.
Eric

2
Ben bakmak için kullanışlı bir veritabanı yok, ama sütun dizin veya değil. Öyleyse, bir aralık taraması ile olur, aksi takdirde, tam bir masa taraması ile hemen hemen kalırsınız. Oracle içinde, NULL'lar dizinde saklanmaz, bu yüzden örnek çok daha iyi olmadığından şüpheleniyorum. Milajınız çok olabilir.
EvilTeach

1
@EvilTeach: Dizinler yalnızca satırların yaklaşık% ~ 10'unu geri çekmediğinizde yardımcı olur. Bundan sonra, tam taramalar başlatılır. Bu durumda, taramayı iki kez olmasa bile en az bir kez alırsınız.
Eric

19

genellikle bu numarayı kullanırım

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


6

Bu biraz zor. Tablonun yalnızca bir sütunu olduğunu varsayalım, o zaman Say (1) ve Say (*) farklı değerler verir.

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

Sorgu Sonuçları

Resimde gördüğünüz gibi, ilk sonuç tablonun 16 satırı olduğunu gösterir. bunlardan iki satır NULL. Kullandığımız Yani Count (*) biz 16 Ama durumunda sayım sonucu aldığım Yani, satır sorgu motoru sayımları numarayı Sayısı (EmpID) o sütun NULL olmayan değer çiftlerini sayılır EmpID . Böylece sonucu 14 olarak aldık.

COUNT (Sütun) kullandığımızda, aşağıda gösterildiği gibi NULL değerlere özen gösterdiğimizden emin olun.

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

hem NULL hem de NULL olmayan değerleri sayar.

Not : Tablo birden çok sütundan oluşsa bile aynı şey geçerlidir. Sayı (1), NULL / NULL olmayan değerlerden bağımsız olarak toplam satır sayısını verecektir. Yalnızca sütun değerleri Say (Sütun) kullanılarak sayıldığında, NULL değerlerine dikkat etmemiz gerekir.


4

Benzer bir sorun vardı: tüm farklı değerleri saymak, boş değerleri 1 olarak saymak. Basit bir sayı bu durumda çalışmaz, çünkü boş değerleri dikkate almaz.

İşte SQL'de çalışan ve yeni değerlerin seçimini içermeyen bir snippet. Temel olarak, farklı bir kez gerçekleştirildiğinde, row_number () işlevini kullanarak satır numarasını yeni bir sütuna (n) döndürün, ardından bu sütunda bir sayım gerçekleştirin:

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

3

İşte iki çözüm:

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

VEYA

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

3

Deneyin

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

Basit!


3

Bunu dene..

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 

2

MS Sql Server kullanıyorsanız ...

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;

Bunu yapmanızı tavsiye etmiyorum ... ama burada var (sonuç olarak aynı tabloda)


2

ISNULL katıştırılmış işlevini kullanın.



Bu da değerli bir cevap. Şahsen COUNT (DISTINCT ISNULL (A, '')) COUNT (DISTINCT A) + SUM'dan (1 BAŞKA 0 SONRA NULL NULL OLDUĞUNDA DURUM) daha iyi çalıştığını buldum
Vladislav

1

onun mysql ise, böyle bir şey deneyebilirsiniz.

select 
   (select count(*) from TABLENAME WHERE a = 'null') as total_null, 
   (select count(*) from TABLENAME WHERE a != 'null') as total_not_null
FROM TABLENAME

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

Bu çirkin, ancak boş değerlerin boş değerlere karşı sayısını gösteren 2 sütun ile tek bir kayıt döndürür.


1

Bu T-SQL'de çalışır. Sadece bir şeyin sayısını sayıyorsanız ve null'ları dahil etmek istiyorsanız, durum yerine COALESCE kullanın.

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

1

Alberto'dan ayrıldığımda, toplamayı ekledim.

 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;

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

1
select count(isnull(NullableColumn,-1))

2
Bu kod soruyu cevaplayabilirken, bu kodun soruyu neden ve / veya nasıl cevapladığı konusunda ek bağlam sağlamak uzun vadeli değerini arttırır.
Vishal Chhodwani

1

Tüm cevaplar yanlış veya son derece güncel değil.

Bu sorguyu yapmanın basit ve doğru yolu COUNT_IFişlevi kullanmaktır .

SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us

0

Tek bir kayıtta istemeniz durumunda:

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

;-)


0

boş olmayan değerleri saymak için

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

null değerleri saymak için

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

1
Operasyon tek sorgu istedi :)
infografnet

0

Tabloyu postgres 10'da oluşturdum ve aşağıdakilerin ikisi de çalıştı:

select count(*) from us

ve

select count(a is null) from us


a IS NULLTRUEveya üretir FALSEve COUNT () tüm NOT NULL değerlerini sayar. Böylece count(a is null)tüm satırların sayısı geri döner.
ypresto

0

Benim durumumda birden çok sütun arasında " null dağılımı " istedim :

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,...

'...' uyarınca, gerektiği kadar daha fazla sütuna kolayca genişletilebilir


-1

A'nın boş olduğu öğe sayısı:

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

A'nın boş olmadığı öğe sayısı:

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

1
Soru tek bir sorgu için.
DreamWave
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.