SQL语句中WHERE IN子句中的NULL用法

4

我有以下查询:

Select 
RPAD(x.QUOTE_ID,20,' ')
from csa_sli_all.T_CONV_XREF_CUST_QUOTE x ,
        csa_sli_all.T_CONV_quote q
where   q.select_indicator is null and 
    q.QUOTE_ID = X.QUOTE_ID and 
    q.HOLD_CODE IN ('CAQ' , NULL )

我的问题是它没有给我所需的结果。

我将最后一条语句改成了

where   q.select_indicator is null and 
    q.QUOTE_ID = X.QUOTE_ID and 
    (q.HOLD_CODE = 'CAQ' or q.hold_code is null)

现在它给我想要的结果。我的问题是:

1 我们不能在WHERE IN子句中使用NULL吗?

2 如果可以,怎么使用?

3 按照逻辑(不是语法:我知道第一个语法是错的),这两种情况会得到相同的答案吗?

7个回答

4

如果您首先将 ANSI_NULLS 设置为 OFF,就可以使用 IN (Null)。

在 ANSI_NULLS 为 ON 的情况下,无法执行与 NULL 的比较(=、>、< 等)。

SET ANSI_NULLS OFF
Select 
RPAD(x.QUOTE_ID,20,' ')
from csa_sli_all.T_CONV_XREF_CUST_QUOTE x ,
        csa_sli_all.T_CONV_quote q
where   q.select_indicator is null and 
    q.QUOTE_ID = X.QUOTE_ID and 
    q.HOLD_CODE IN ('CAQ' , NULL )

应该可以正常工作。


好的,这听起来是我强烈反对任何人这样做的事情。仅仅为了比较NULL而忽略标准?这可能会导致在开发、维护和部署应用程序时产生重大混乱。 - Dmytro Shevchenko

3

使用IN时,不能在where子句中使用null值,如果需要使用,请像这样使用:

q.HOLD_CODE in ('CAQ', ...) or q.hold_code is null

如果你想查找空值,你必须始终使用 "is null",因此无法在IN语句中使用它。

2

IN语句中,您不能使用NULL,因为IN应用标准的=运算符。当比较NULL时,这个运算符会失败。

这就像写SELECT NULL = NULL一样。返回值将是NULL


2

我不确定,但我认为你不能在where子句中使用NULL。

我经常混淆= NULL和IS NULL的区别。

为什么不使用ISNULL,例如...

 WHERE ISNULL(q.HOD_CODE,'CAQ') = 'CAQ'

2

NULL IN (NULL)的结果为UNKNOWN。如果要比较null值,应该使用is null操作符。Null有其特定的处理方式。

示例:

select case when null in (null) then 1 else 0 end

returns 0

记住 Codd 的第三个规则:

规则 3: 对 null 值的系统处理: DBMS 必须允许每个字段保持 null (或空)。具体而言,它必须支持一种“缺失信息和不适用信息”的表示方式,该表示方式是系统化的,与所有常规值(例如,在数字值的情况下,“与零或任何其他数字”不同)相区别,并且独立于数据类型。这也意味着这些表示必须以系统化的方式由 DBMS 进行操作。


还记得 null 值不在 Codd 的原始关系模型中吗?他后来拒绝了你引用的规则,支持两种 null 值的提议,但这个提议几乎被普遍拒绝了。参见:维基百科 Null (SQL):“在数据库管理的关系模型版本2中,Codd 提出 SQL 实现的 Null 是有缺陷的,应该用两个不同的 Null 类型标记来替换...” - onedaywhen
@onedaywhen,哦!感谢您用这个引号说明了文章的内容。我认为此时此刻这个代码建议已经被遗弃了:“……由于额外的复杂性,多个Null类型值的想法并没有得到广泛的认可。” - dani herrera
底线:我认为你不能用Codd来为SQL空值辩护,因为他拒绝了SQL空值,其他人也拒绝了Codd的空值! - onedaywhen
@onedaywhen,对于你来说,在数据库中Null概念的主要作者参考文献是什么? - dani herrera
主要作者在我看来应该是Chris Date。Codd和Date都有一篇有趣的文章,题为《无关紧要的事情》(Much Ado About Nothing)。如果你正在寻找对SQL中空值的批判,请考虑阅读Hugh Darwen的这篇文章:《关于空值的问题》(On the Nothing That's Wrong With Nulls)。 - onedaywhen

2
您需要使用 is null 而不是 = null
在将字段与 NULL 进行比较时,SQL 查询应该使用 IS 运算符代替 "=" 运算符。原因是如果连接的 ANSI_NULLS 选项为 On,则与 NULL 值进行比较的表达式将不会返回 true 或 false 值,而是将返回未知值。为了更简单地说明,如果一个名为 col1 的列包含两个 NULL 值的表 xxx ,则此查询将导致获取零条记录:
Select * from xxx where col1 = NULL

同时,这个查询将会返回两条记录:
Select * from xxx where col1 IS NULL

然而,如果您将ANSI_NULLS关闭,则这两个查询都将返回两条记录。

1

不要使用子查询,而是使用连接。举个例子,如果你正在使用SQL Server,可以这样做(填写你的字段):

SELECT yourField, yourField2 
FROM yourTable t1
INNER JOIN yourTable2 t2 ON t1.Id = t2.Id
WHERE t1.field is null
AND (t1.code = 'CAQ' OR t1.code IS NULL)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接