验证列是否具有空值

时间:2009-04-21 06:24:17

标签: sql sql-server performance oracle null

如果特定列是否具有空值,哪种SQL会更快验证,为什么?

1)SELECT * FROM TABLE1 WHERE COL1 IS NULL

执行此查询,然后检查您是否能够读取任何记录。如果是,则存在空值。

2)SELECT COUNT(COL1)FROM TABLE1 WHERE COL1 IS NULL

读取返回的计数以确定是否存在任何空记录

使用Oracle10g和SQLServer2005。

4 个答案:

答案 0 :(得分:6)

Count(columnName)永远不会计算NULL值,count指定列名时会跳过NULLS,并在使用*

时计算NULLS

运行此

CREATE TABLE testnulls (ID INT)
INSERT INTO testnulls VALUES (1)
INSERT INTO testnulls VALUES (2)
INSERT INTO testnulls VALUES (null)

SELECT count(*) FROM testnulls WHERE ID IS NULL --1

SELECT count(ID) FROM testnulls WHERE ID IS NULL --0

我会使用exists而不是因为它是一个布尔运算,并且会在第一次出现NULL时停止

IF EXISTS (SELECT 1 FROM testnulls WHERE ID IS NULL)
PRINT 'YES'
ELSE
PRINT 'NO'

答案 1 :(得分:5)

以kquinn的答案为基础,在Oracle中将是

SELECT COL1 FROM TABLE1 WHERE COL1 IS NULL AND ROWNUM = 1;
  

这样,DBMS只需要在给出答案之前读取一行;

然而,该声明具有误导性。它必须读取所有行,直到找到具有缺失列值的行。然后它可以停止并返回该行。

如果没有这样的行,它将读取整个表格。

  

因此可以使用COL1上的索引来满足查询,从而使查询更快。

仅指定COL1不会产生太大影响,至少在Oracle上,其中(常规B树)索引不能用于查找NULL值。

如果您有兴趣稍后识别该行,您可能还想选择更多列(例如主键值)。

答案 2 :(得分:4)

我不了解Oracle,但对于SQL Server,这个选项可能是最快的:

SELECT TOP 1 COL1 FROM TABLE1 WHERE COL1 IS NULL;

这样,DBMS只需要在给出答案之前读取一行;其他选项必须读取所有非空行。我已经指定了COL1而不是*,因此可以使用COL1上的索引来满足查询,从而使查询更快。

答案 3 :(得分:0)

多个解决方案(列包含一些NULL |列全部为空*测试单列|使用表格结果测试多个列)

如果您需要测试多个列,可以使用以下内容:

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

我希望这会有所帮助。