Find if any columns that contain null in SQL Server

时间:2016-12-02 05:18:24

标签: sql sql-server

I new to SQL, I am having some difficulty solving this problem.

I want to write the select query which returns all those rows which have the null value in it.

I have more than 50 columns on the table and can be added some extra column it and because of that I getting difficult to write where condition.

AFAIK we can use is null but I don't want to repeat it for that much columns.

Please help me solve it. Let me know if any additional information required.

5 个答案:

答案 0 :(得分:3)

You can try this dynamic SQL query. This query will return row if any column contain null value.

DECLARE @tb NVARCHAR(255) = N'dbo.[tablename]';

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)
      AND [is_nullable]=1;

EXEC sp_executesql @sql;

答案 1 :(得分:3)

一种简单的方法(因为它不需要明确列出列)是

WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' as ns)
SELECT *
FROM   t1 x
WHERE  (SELECT x.*
        FOR xml path('row'), elements xsinil, type
        ).exist('(//*/@ns:nil)') = 1

虽然它确实有完全不需要的转换为XML的开销。 http://rextester.com/VTV64079

答案 2 :(得分:0)

除了为什么设计 - 如此被忽视 - 直到现在的问题,还有许多替代方案。

可悲的是,除非您能保证这些50多列中的某些列可能为空,否则您将使用复杂的谓词或表扫描。

由于显然无法干净地使用谓词,因此请使用干净的表扫描来测试值并运行与布尔语句匹配的内部联接。

sigsuspend()

这种方式WITH CTE AS (SELECT IIF (col1 IS NULL, 1, (IIF(col2 IS NULL, 1, etc) ) ) as FOUND -- if clears, return 0 FROM TABLEA AS A) SELECT A.* FROM CTE A INNER JOIN TABLEA AS B ON A.ID = B.ID WHERE A.FOUND = 1 可以对其进行关系处理,并且您的谓词是干净的。 SQL Server语句只是将一行值与IIF值的检查进行比较(我将测试其他方式来声明这些函数可以改变),这比尝试使用谓词复杂得多在一个复杂的50!逻辑噩梦。

内联函数的关键优势在于它们可能是优化的声音,它们被设计用于粗略地处理数据,而你的谓词用于关系比较(SARG)

答案 3 :(得分:0)

试试这个:用表格替换table_name

DECLARE @COLNAME VARCHAR(MAX),@QUERY VARCHAR(MAX),@TABLE VARCHAR(MAX)
DECLARE @TEST TABLE(ID INT)
DECLARE @NULLS TABLE([TABLE] VARCHAR(MAX), [COLUMN] VARCHAR(MAX),[HAS_NULL] VARCHAR(MAX))
SET @TABLE='TABLE_NAME'
DECLARE C CURSOR FOR 
SELECT NAME FROM SYS.ALL_COLUMNS WHERE OBJECT_ID=(SELECT OBJECT_ID FROM SYS.TABLES WHERE NAME=@TABLE)
OPEN C
FETCH NEXT FROM C INTO @COLNAME
WHILE @@FETCH_STATUS=0
BEGIN
SET @QUERY='SELECT COUNT(1) FROM '+@TABLE+' WHERE '+@COLNAME+' IS NULL' 
INSERT INTO @TEST EXEC (@QUERY)
IF(SELECT TOP 1 ID FROM @TEST)>0
BEGIN
INSERT INTO @NULLS VALUES ( @TABLE,@COLNAME,'NULL VALUES')
END
ELSE 
BEGIN
INSERT INTO @NULLS VALUES ( @TABLE,@COLNAME,'NO NULL VALUES')
END
DELETE FROM @TEST
FETCH NEXT FROM C INTO @COLNAME
END
CLOSE C
DEALLOCATE C


SELECT * FROM @NULLS

答案 4 :(得分:0)

您是否希望找到所有指定列为空?

;WITH tb(ID,col1,col2,col3,col4,col5,col6,col7,col8,col9)AS(
    SELECT 1,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL UNION
    SELECT 2,NULL,NULL,NULL,NULL,NULL,NULL,3,NULL,NULL UNION
    SELECT 3,1,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL UNION
    SELECT 4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL 

)
SELECT * FROM tb
WHERE COALESCE(col1,col2,col3,col3,col5,col6,col7,col8,col9) IS NULL

将返回id = 4

ID          col1        col2        col3        col4        col5        col6        col7        col8        col9
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
4           NULL        NULL        NULL        NULL        NULL        NULL        NULL        NULL        NULL

使用动态声明检查哪个列为NULL:

CREATE TABLE tb(ID INT ,col1 INT ,col2 INT ,col3 INT ,col4 INT ,col5 INT ,col6 INT ,col7 INT ,col8 INT ,col9 INT )
INSERT INTO tb
SELECT 1,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL UNION
SELECT 2,NULL,NULL,NULL,NULL,NULL,NULL,3,NULL,NULL UNION
SELECT 3,1,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL UNION
SELECT 4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL 

DECLARE @cols NVARCHAR(max),@sql NVARCHAR(max)
SELECT @cols=ISNULL(@cols+',','')+'('''+c.name+ ''',['+c.name+'])' FROM sys.all_columns AS c WHERE OBJECT_NAME(c.object_id)='tb'
PRINT @cols
SET @sql='
SELECT ID,c.col_title,CASE WHEN c.col_value IS NULL THEN ''NULL NULL'' ELSE ''HAS VALUE'' END  AS COMMENT FROM dbo.tb
CROSS APPLY(VALUES'+@cols+') c(col_title,col_value)'
PRINT @sql
EXEC (@sql)
ID          col_title COMMENT
----------- --------- ---------
1           col1      HAS VALUE
1           col2      NULL NULL
1           col3      NULL NULL
1           col4      NULL NULL
1           col5      NULL NULL
1           col6      NULL NULL
1           col7      NULL NULL
1           col8      NULL NULL
1           col9      NULL NULL
1           ID        HAS VALUE
2           col1      NULL NULL
2           col2      NULL NULL
2           col3      NULL NULL
2           col4      NULL NULL
2           col5      NULL NULL
2           col6      NULL NULL
2           col7      HAS VALUE
2           col8      NULL NULL
2           col9      NULL NULL
2           ID        HAS VALUE
3           col1      HAS VALUE
3           col2      HAS VALUE
3           col3      NULL NULL
3           col4      NULL NULL
3           col5      NULL NULL
3           col6      NULL NULL
3           col7      NULL NULL
3           col8      NULL NULL
3           col9      NULL NULL
3           ID        HAS VALUE
4           col1      NULL NULL
4           col2      NULL NULL
4           col3      NULL NULL
4           col4      NULL NULL
4           col5      NULL NULL
4           col6      NULL NULL
4           col7      NULL NULL
4           col8      NULL NULL
4           col9      NULL NULL
4           ID        HAS VALUE