단일 쿼리에서 null 및 null이 아닌 값 계산


141

나는 테이블이있다

create table us
(
 a number
);

이제 다음과 같은 데이터가 있습니다.

a
1
2
3
4
null
null
null
8
9

지금은 널 (null) 카운트 단일 쿼리가 필요 하고 열 A하지 null 값을


3
안녕하세요, 어떤 언어 데이터베이스에서 이런 종류의 계산 데이터베이스 코드가 필요한
가요?

2
나는 하나의 답변에 선택 카운트 (*)의 간단한 조합이 포함되어 있지 않다는 것에 놀랐습니다 ...
Lieven Keersmaekers

1
@Lieven : 왜 지구상에서 union여기 를 사용 하시겠습니까? Montecristo의 대답은 지금까지 최고의 솔루션입니다.
Eric

1
OP는 단일 쿼리로 원하기 때문입니다. 몬테 크리스토의 대답은 실제로 최고의 솔루션입니다 ... 그는 단지 노동 조합을 추가해야합니다 :)
Lieven Keersmaekers

1
그리고 그것이 제목을 읽을 때 얻는 것입니다. 편집합니다.
Eric

답변:


231

이것은 Oracle 및 SQL Server에서 작동합니다 (다른 RDBMS에서 작동하도록 할 수 있음).

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

또는:

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

1
구분을 사용 count(*)하고 count(a)또한 잘 작동group by
섀넌

1
@shannon 동의 COUNT(a)합니다. 추가 할 유용한 주석이지만 스택에 따라 경고 / 오류가 발생하고 코드에 주석이 필요할 수 있습니다. SUM방법 을 선호합니다 .
Richard

4
선호 count(*)count(1)
레이 조

61

올바르게 이해하면 열에서 모든 NULL과 NOT NULL을 모두 계산하려고합니다 ...

그것이 맞다면 :

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

주석을 읽은 후 전체 쿼리를 갖도록 편집했습니다.]


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 : 가장 간단하고 빠른 방법입니다. 나는 모든 대답이 이것에 맞지 않을 때 충격을 받았다.
Eric

6
예, 아니요 나는 그가 단지 하나의 쿼리에서 NULL이 아닌 NULL의 숫자를 원한다고 생각합니다 ... 당신은 두 개의 쿼리에서 그것을하는 방법을 말하고 있습니다 ...
Romain Linsolas

@romaintaz : 그렇습니다. 제목으로 질문을 읽었습니다. 다섯 번의 편집에서 아무도 고칠 생각이 없었습니다. 예쉬
Eric

@ romaintaz : 네, 맞습니다. 나는 이것을 "한 번의 null을 발견하기 위해 한 번의 쿼리 실행"으로 가져갔습니다. 왜 ^^ '가 올바른지, 감사합니다.
Alberto Zaccagni

1
@Montecristo : 제목 만 계산을 요구했기 때문에 null:)
Eric

42

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

3
SQL Server에서도 비슷한 구문이 작동합니다. 또한이 방법으로 테이블을 한 번만 스캔합니다. UNION 솔루션은 두 개의 테이블 스캔을 수행합니다. 작은 테이블에는 적합하지 않으며 거대한 테이블에는 매우 중요합니다.
Philip Kelley

2
SQL Server 만 변경 "Null values"하면됩니다 'Null values'. 작은 따옴표는 두 배가 아닙니다.
Eric

1
SQLServer에는 사용 인덱스 스캔을 두 대이 쿼리에 대한 인덱스가 추구 조합을 사용하여. 행이 40.000 인 테이블에는 속도 차이가 없습니다.
Lieven Keersmaekers

1
11.332.581 개의 행이있는 테이블 에는 두 개의 테이블 스캔 이 있으며 눈에 띄는 속도 차이가 없습니다 (실제로 유니온이 약간 빠릅니다).
Lieven Keersmaekers

1
이것은 Oracle 11g에서 작동하지 않았습니다. @ user155789 버전은 "case when a is null then 1 else 0 end"로 게시되었습니다.
Steve

25

쿼리를 이해 했으므로이 스크립트를 실행하고 Total Null, Total NotNull 행,

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

23

널이 아닌 경우

select count(a)
from us

널용

select count(*)
from us

minus 

select count(a)
from us

그 후

SELECT COUNT(A) NOT_NULLS
FROM US

UNION

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

일을해야한다

열 제목이 올바르게 나옵니다.

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

내 시스템에 대한 일부 테스트에서는 전체 테이블 스캔 비용이 발생합니다.


4
좋은 그레이비,이 쿼리들에 대한 실행 계획을 보라. 테이블 스캔을 왼쪽과 오른쪽으로 시작합니다. 특히 피의 간단한 진술 ( select count(*) from t where a is null)이 있는 곳에서 특히 그렇습니다 .
Eric

2
보기 쉬운 데이터베이스가 없지만 열이 색인화되어 있는지 여부입니다. 그렇다면 범위 스캔을 통해 발생하며, 그렇지 않으면 전체 테이블 스캔으로 거의 남아 있습니다. 오라클에서는 NULL이 인덱스에 저장되지 않으므로 예제가 훨씬 좋지 않다고 생각합니다. 당신의 마일리지가 매우 높을 수 있습니다.
EvilTeach

1
@EvilTeach : 인덱스는 행의 ~ 10 %를 뒤로 당기지 않을 때만 유용합니다. 그 후 전체 스캔이 시작됩니다. 이 경우 두 번이 아니라면 한 번 이상 스캔을 받게됩니다.
Eric

19

보통 나는이 트릭을 사용

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

조금 까다 롭습니다. 테이블에 열이 하나만 있다고 가정하면 Count (1) 및 Count (*)는 다른 값을 제공합니다.

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

쿼리 결과

이미지에서 볼 수 있듯이 첫 번째 결과는 테이블에 16 개의 행이 있음을 보여줍니다. 다음 중 두 행이 NULL입니다. 따라서 Count (*)를 사용할 때 쿼리 엔진은 행 수를 계산하므로 결과는 16으로 계산됩니다. 그러나 Count (empid)의 경우 empid 열에서 NULL이 아닌 값을 계산했습니다 . 결과는 14입니다.

따라서 COUNT (Column)를 사용할 때마다 아래와 같이 NULL 값을 처리해야합니다.

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

NULL 값과 NULL이 아닌 값을 모두 계산합니다.

참고 : 테이블이 둘 이상의 열로 구성된 경우에도 동일한 사항이 적용됩니다. Count (1)은 NULL / Non-NULL 값에 관계없이 총 행 수를 제공합니다. Count (Column)를 사용하여 열 값을 계산할 때만 NULL 값을 처리해야합니다.


4

비슷한 문제가 있습니다. 모든 고유 값을 계산하고 null 값도 1로 계산합니다. 이 경우 널 (null) 값을 고려하지 않으므로 단순 개수는 작동하지 않습니다.

다음은 SQL에서 작동하며 새 값을 선택하지 않는 스 니펫입니다. 기본적으로 고유를 수행 한 후에는 row_number () 함수를 사용하여 새 열 (n)의 행 번호를 반환 한 다음 해당 열에서 카운트를 수행하십시오.

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

3

다음은 두 가지 해결책입니다.

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

또는

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


3

이 시도..

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를 사용하는 경우 ...

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;

나는 당신이 이것을하는 것을 권장하지 않지만 ... 여기 당신은 그것을 가지고 있습니다 (결과와 같은 테이블에)


2

ISNULL 내장 함수를 사용하십시오.



이것은 또한 가치있는 답변입니다. 나는 개인적으로 더 나은 다음 + (DISTINCT A) SUM을 COUNT 작동 COUNT (DISTINCT ISNULL (A를, '')) 발견 (CASE 때 IS NULL THEN 1 ELSE 0 END)
블라디슬라프

1

mysql이라면 이와 같은 것을 시도해 볼 수 있습니다.

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

그것은 추악하지만 null 수와 비 null 수를 나타내는 2 개의 열이있는 단일 레코드를 반환합니다.


1

이것은 T-SQL에서 작동합니다. 무언가의 수를 세고 널을 포함하려면 대소 문자 대신 COALESCE를 사용하십시오.

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를 기반으로 롤업을 추가했습니다.

 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 count(isnull(NullableColumn,-1))

2
이 코드는 질문에 대답 할 수 있지만,이 코드가 질문에 응답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
Vishal Chhodwani

1

모든 답변이 잘못되었거나 매우 오래되었습니다.

이 쿼리를 수행하는 간단하고 올바른 방법은 COUNT_IF함수를 사용하는 것입니다.

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

0

단일 레코드로 원할 경우를 대비하여 :

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

;-)


0

널이 아닌 값을 세는 것

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

널값 계산

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

1
영업 이익은 : 단일 쿼리 요청
infografnet

0

postgres 10에서 테이블을 만들었고 다음 두 가지 모두 작동했습니다.

select count(*) from us

select count(a is null) from us


a IS NULL생산 TRUE또는 FALSE, 및 COUNT () 모든 NOT NULL 값을 계산합니다. 따라서 count(a is null)모든 행의 개수를 반환합니다.
ypresto

0

필자의 경우 여러 열 사이에 " null 분포 "를 원했습니다 .

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

'...'에 따라 필요한만큼 많은 열로 쉽게 확장 할 수 있습니다.


-1

a가 null 인 요소 수 :

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

a가 null이 아닌 요소 수 :

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

1
질문은 단일 쿼리에 대한 것입니다.
DreamWave
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.