NULL이 NULL로 그룹화 한 레코드를 어떻게 반환합니까?
문제
나는 테이블이 있습니다 processed_timestamp
열 - 레코드가 처리 된 경우 해당 필드에는 처리 된 데이터가 포함되어 있습니다. 그렇지 않으면 NULL입니다.
두 행을 반환하는 쿼리를 쓰고 싶습니다.
NULL xx -- count of records with null timestamps
NOT NULL yy -- count of records with non-null timestamps
그게 가능합니까?
업데이트: 테이블은 상당히 크기 때문에 효율성이 중요합니다. 각 총계를 개별적으로 계산하기 위해 두 개의 쿼리를 실행할 수 있지만 피할 수 있다면 테이블에 두 번 닿지 않도록하고 싶습니다.
해결책
신탁:
NVL2 그룹 (필드, 'NOT NULL', 'NULL')
다른 팁
MySQL에서 당신은 같은 일을 할 수 있습니다
SELECT
IF(ISNULL(processed_timestamp), 'NULL', 'NOT NULL') as myfield,
COUNT(*)
FROM mytable
GROUP BY myfield
T-SQL (MS SQL Server)에서는 다음과 같습니다.
SELECT
CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END FieldContent,
COUNT(*) FieldCount
FROM
TheTable
GROUP BY
CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END
다음을 시도해보십시오. 공급 업체 중립입니다.
select
'null ' as type,
count(*) as quant
from tbl
where tmstmp is null
union all
select
'not null' as type,
count(*) as quant
from tbl
where tmstmp is not null
우리의 로컬 DB2 Guru가 이것을 살펴보면, 그는 동의합니다. 그는 현재까지 제시된 솔루션 중 어느 것도 (이것을 포함하여) 전체 테이블 스캔을 피할 수는 없습니다 (타임 스탬프가 색인화되지 않거나 인덱스 위상이없는 경우 테이블의 전체 테이블). 그들은 모두 테이블의 모든 레코드를 정확히 한 번 스캔합니다.
모든 사례/if/nvl2 () 솔루션은 각 행에 대해 널 투 스 트링 변환을 수행하여 DBMS에 불필요한 부하를 도입합니다. 이 솔루션에는 그 문제가 없습니다.
그것이 오라클이라면 당신은 할 수 있습니다 :
select decode(field,NULL,'NULL','NOT NULL'), count(*)
from table
group by decode(field,NULL,'NULL','NOT NULL');
다른 DBS도 비슷한 속임수를 허용한다고 확신합니다.
스튜어트,
이 솔루션을 고려할 수도 있습니다. 공급 업체가 비특이적입니다.
SELECT count([processed_timestamp]) AS notnullrows,
count(*) - count([processed_timestamp]) AS nullrows
FROM table
효율성에 관해서는, 이것은 2x 인덱스가 한 행에 결과를 포함시킴으로써/테이블 스캔을 추구하는 것을 피합니다. 결과에서 절대적으로 2 행이 필요하면 통합 응집체로 인해 세트 위의 2 개의 패스를 피할 수 없을 수 있습니다.
도움이 되었기를 바랍니다
또 다른 MySQL 방법은 사용하는 것입니다 CASE
운영자, 이는보다 더 많은 대안으로 일반화 될 수 있습니다 IF()
:
SELECT CASE WHEN processed_timestamp IS NULL THEN 'NULL'
ELSE 'NOT NULL' END AS a,
COUNT(*) AS n
FROM logs
GROUP BY a
데이터베이스에 테이블에 대한 효율적인 카운트 (*) 기능이있는 경우 더 작은 숫자를 계산하고 빼게 될 수 있습니다.
SQL Server (2012 년부터 시작) :
SELECT IIF(ISDATE(processed_timestamp) = 0, 'NULL', 'NON NULL'), COUNT(*)
FROM MyTable
GROUP BY ISDATE(processed_timestamp);
나는 개인적으로 Pax의 솔루션을 좋아하지만, 최근에 한 행이 반환 된 경우 (최근에와 같이) MS SQL Server 2005/2008에서 CTE를 사용하여 두 쿼리를 "스택"할 수 있습니다.
with NullRows (countOf)
AS
(
SELECT count(*)
FORM table
WHERE [processed_timestamp] IS NOT NULL
)
SELECT count(*) AS nulls, countOf
FROM table, NullRows
WHERE [processed_timestamp] IS NULL
GROUP BY countOf
도움이 되었기를 바랍니다
T-SQL] :
select [case], count(*) tally
from (
select
case when [processed_timestamp] is null then 'null'
else 'not null'
end [case]
from myTable
) a
그리고 목요일 오후 6시 이후, 어제 정오와 오후 2시 사이에 파티션을 만들고 싶은 다른 값에 대해 사례 진술에 추가 할 수 있습니다.
Select Sum(Case When processed_timestamp IS NULL
Then 1
Else 0
End) not_processed_count,
Sum(Case When processed_timestamp Is Not NULL
Then 1
Else 0
End) processed_count,
Count(1) total
From table
편집 : 신중하게 읽지 않았으며, 이것은 단일 행을 반환합니다.
오라클에서
SELECT COUNT(*), COUNT(TIME_STAMP_COLUMN)
FROM TABLE;
count (*) 모든 행의 수를 반환합니다.
count (column_name) null이 아닌 행의 수를 반환합니다.
SELECT COUNT(*) - COUNT(TIME_STAMP_COLUMN) NUL_COUNT,
COUNT(TIME_STAMP_COLUMN) NON_NUL_COUNT
FROM TABLE
일을해야합니다.
열이 색인화되면 어떤 종류의 범위 스캔으로 끝나고 실제로 테이블을 읽지 않을 수 있습니다.
T-SQL (SQL-Server)의 또 다른 방법
select count(case when t.timestamps is null
then 1
else null end) NULLROWS,
count(case when t.timestamps is not null
then 1
else null end) NOTNULLROWS
from myTable t