2016-12-02 55 views
3

我是SQL新手,我在解决这个问题时遇到了一些困难。查找在SQL Server中是否有包含null的列

我想写它返回所有那些在它的空值的行选择查询。

我有表50多列,可以添加一些额外的列,并因为我越来越难写WHERE条件。

据我所知,我们可以使用is null,但我不想再重复它那么多列。

请帮我解决这个问题。让我知道是否需要任何其他信息。

+2

你*有*给所有列在where子句中。 – GurV

+0

您将不得不使用动态SQL自动生成where子句。否则,你运气不好 - 你需要为允许空值的所有列指定它。这就是说,我不确定为什么一张桌子需要50列,为什么你需要检查它们中的任何一个是否为空;我的猜测是,表格的设计首先不是最佳的。 – ZLK

+1

这是设计进场的地方。空值来自哪里?为什么未知影响所有50列?如果你不能强制一个NOT NULL作为列约束,那么你的表甚至可以创建1NF,更不用说2NF(标准化)了。这是一个事实或维度表?此查询回答了哪些问题? –

回答

3

你可以试试这个动态的SQL查询。如果任何列包含空值,此查询将返回行。

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; 
+0

并摧毁可能只是做一些疯狂的查询的可怜的优化器。 –

+0

@dreamer你是最受欢迎的:) – Bharat

0
从个为什么

除了为什么-被设计那么被忽视,直到-现在的问题,也有一些替代品。

可悲的是,除非你能保证一些人50+列可能是空的,你要么要使用一个复杂的断言或表扫描。

由于这显然不会是能够干净地使用谓词,用干净的表扫描,以测试值并运行一个内部联接相匹配的布尔语句。

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声明只是随用随取一个比较行值NULL值(我将考验此声明,以了解如何功能可以改变的替代方式),这显著不太复杂的比试图使用谓词在复杂的50!逻辑的噩梦。

的关键优势,内联函数是,他们很可能会被优化sonce他们的目的是用数据cursively处理,而你的谓词是关系比较(个SARG)

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 [email protected]) 
OPEN C 
FETCH NEXT FROM C INTO @COLNAME 
WHILE @@FETCH_STATUS=0 
BEGIN 
SET @QUERY='SELECT COUNT(1) FROM '[email protected]+' WHERE '[email protected]+' 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 
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

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'[email protected]+') 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 
相关问题