将常量与空集进行比较时,Db2 IN 谓词产生 NULL
Posted
技术标签:
【中文标题】将常量与空集进行比较时,Db2 IN 谓词产生 NULL【英文标题】:Db2 IN predicate yields NULL when comparing constant with empty set 【发布时间】:2020-04-14 08:40:50 【问题描述】:考虑这个查询:
SELECT
1 IN (
SELECT 1 FROM SYSIBM.dual WHERE FALSE
) AS a,
1 IN (
SELECT NULL FROM SYSIBM.dual WHERE FALSE
) AS b
FROM SYSIBM.dual;
两个谓词都检查常量值是否在空集中。唯一的区别是其中一个空集有一个 NULL
文字,在我看来是无关紧要的。两个结果都应该是FALSE
,因为空集中没有任何值。但是,我得到了这个:
A|B|
-|-|
0| |
A
是 FALSE
,正如预期的那样,但 B IS NULL
,这没有任何意义。使用CAST(NULL AS INT)
不会改变任何东西,以防这可能是因为未知数据类型。这种行为是否有合理的解释或者这是一个错误? mysql 和 PostgreSQL 都为 B
返回 FALSE
。
-- PostgreSQL:
SELECT
1 IN (
SELECT 1 WHERE FALSE
) AS a,
1 IN (
SELECT CAST(NULL AS INT) WHERE FALSE
) AS b
-- MySQL:
SELECT
1 IN (
SELECT 1 WHERE FALSE
) AS a,
1 IN (
SELECT NULL WHERE FALSE
) AS b
一个更简单的示例暴露了一个类似的错误(可能与 Db2 的 BOOLEAN
类型的有缺陷的实现有关一般):
SELECT NULL OR FALSE AS a, FALSE OR NULL AS b FROM SYSIBM.dual;
产生:
A|B|
-|-|
0| |
显然是另一个错误。 OR
中操作数的顺序无关紧要。
我正在使用 Db2 LUW v11.5.0.0
【问题讨论】:
这是一个错误。 A 和 B 都应该是 FALSE。 不,这是条件检查而不是数据选择,这只是其他数据库中的错误语法,尽管您的 db2 可能出于调试目的支持该语法。尝试在 oracle 中运行相同的语法,否则您会得到错误的语法或尝试select from.. Where your condition
它不会给出任何记录
@HimanshuAhuja:完全可以模仿其他方言的语法。但这不是这个问题的目的。
您能向 IBM 支持部门提出这个问题吗?
很公平。我将在 IBM 内部接受您的观察
【参考方案1】:
由于IS NULL
使用IN
不可用,与空值相比,IN 给出空值
您得到了正确的输出(因为这些是条件或类似测试用例)结果不是布尔值,而是 0 或数据(真)的形式,因为第一个查询评估为假,这意味着 0 等效于 IN 没有给出值将是 0就像 if(签入数据)。
但是,第二次它返回 null,因为在 NULL 情况下,IN 比较失败,因为 IS NULL
不可用,因此它认为是 null。
我猜这种行为有点像三元条件运算符
Select IN? 0(true) |DATA (includes
NULL) (false)
【讨论】:
我很清楚A IN SET
与A = ANY SET
相同,与A = e1 OR A = e2 ... OR A = en
相同,如果有ei IS NULL
,不影响结果感谢 3VL。但这丝毫不能解释我的观察(关于空集)。
SQL 标准说 “如果 T 为空或隐含的 False
。
你真的读过我的回答吗?它的运行状态不是数据的选择 db2 支持这种调试语法。使用相同条件选择记录将不会给出记录以上是关于将常量与空集进行比较时,Db2 IN 谓词产生 NULL的主要内容,如果未能解决你的问题,请参考以下文章
使用 like 谓词(模式匹配)对 DB2 Z/oS 的 SQL 查询进行性能调优