답변:
더 적은 (읽기 : 제로) 손글씨가없는 @ db2의 답변 확장 :
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;
JNK의 의견에 따라 모든 열을 나열해야합니다.
WHERE c1 IS NULL OR c2 IS NULL OR c3 IS NULL
이것을 피하는 다소 덜 효율적인 접근법은 아래에 있습니다.
;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
기본 제공 구문은 없지만 Management Studio에는 쿼리를 빠르게 생성 할 수있는 편리한 기능이 있습니다.
개체 탐색기에서 원하는 테이블로 드릴 다운하고 확장 한 다음 전체 "Columns"폴더를 빈 쿼리 편집기로 끕니다. 이렇게하면 쉼표로 구분 된 열 목록이 쿼리에 추가됩니다.
그런 다음 찾기 및 바꾸기를 엽니 다. "Find What"을 ,
설정하고 "Replace With"를 IS NULL OR
(앞 공백으로) 설정 한 다음 Replace All을 누르십시오. 순서대로 마지막 하나를 손으로 정리해야합니다.
여전히 추악하지만 노동 집약도 덜 추합니다.
여러 열을 테스트해야하는 경우 다음을 사용할 수 있습니다.
Column_1 Column_2 Column_3
-------- -------- --------
1 2 NULL
1 NULL NULL
5 6 NULL
먼저 NULL을 테스트하고 계산하십시오.
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
NULL 수를 나타냅니다.
Column_1 Column_2 Column_3
0 1 3
결과가 0이면 NULL이 없습니다.
둘째 , 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
...하지만 여기서는 NULL이 아닌 값을 계산하므로 다음과 같이 단순화 할 수 있습니다.
select
count(Column_1) as Column_1,
count(Column_2) as Column_2,
count(Column_3) as Column_3,
from TestTable
어느 쪽이든 산출합니다 :
Column_1 Column_2 Column_3
3 2 0
결과가 0 인 경우 열은 전체적으로 NULL로 구성됩니다.
마지막으로 특정 열만 확인하면 첫 번째 히트에서 중지해야하므로 TOP 1이 더 빠릅니다. 그런 다음 선택적으로 count (*)를 사용하여 부울 스타일 결과를 제공 할 수 있습니다.
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 = NULL이 없음, 1 = 적어도 하나의 NULL이 있음
또는
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 = 모두 NULL입니다. 1 = NULL이 아닌 하나 이상이 있습니다.
이게 도움이 되길 바란다.
UNPIVOT은 열을 행으로 변환합니다. 이 과정에서 NULL 값을 제거합니다 ( reference ).
주어진 입력
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);
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;
출력을 생성합니다
| ID | ColName | ColValue |
|----|---------|----------|
| 1 | c1 | 12 |
| 1 | c2 | 13 |
| 2 | c2 | 14 |
| 3 | c1 | 15 |
슬프게도 4 행은 NULL 만 있기 때문에 완전히 제거되었습니다! 소스 쿼리에 더미 값을 주입하여 편리하게 다시 도입 할 수 있습니다.
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;
ID에서 행을 집계하여 널이 아닌 값을 계산할 수 있습니다. 소스 테이블의 총 열 수를 비교하면 하나 이상의 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;
주입 된 더미 열의 경우
소스 테이블 #t
+ 1 의 열 수로 3을 계산
합니다 .ID의 경우 1이며 UNPIVOTED가 아닙니다.
카탈로그 테이블을 검사하여 런타임시이 값을 얻을 수 있습니다.
결과에 결합하여 원래 행을 검색 할 수 있습니다.
NULL 이외의 값을 조사하려면 where 절에 포함시킬 수 있습니다.
...
) as unpvt
where ColValue <> '' -- will eliminate empty strings
UNPIVOT을 통해 전달되는 식별자가 필요합니다. 열쇠가 가장 좋습니다. 존재하지 않는 경우 ROW_NUMBER () 창 함수 로 삽입 할 수 있지만 실행 비용이 많이들 수 있습니다.
모든 열은 UNPIVOT 절 안에 명시 적으로 나열되어야합니다. @ db2가 제안한 것처럼 SSMS를 사용하여 끌 수 있습니다. Aaron Bertrand의 제안과 같이 테이블 정의가 샴페인 일 때는 역동적이지 않습니다. 그러나 이것은 거의 모든 SQL의 경우입니다.
다소 제한된 데이터 세트의 경우 실행 계획은 클러스터형 인덱스 스캔 및 스트림 집계입니다. 이는 테이블 및 많은 OR 절을 연속 스캔하는 것보다 메모리 비용이 더 비쌉니다.