将常量与空集进行比较时,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| |

AFALSE,正如预期的那样,但 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 SETA = ANY SET相同,与A = e1 OR A = e2 ... OR A = en相同,如果有ei IS NULL,不影响结果感谢 3VL。但这丝毫不能解释我的观察(关于空集)。 SQL 标准说 “如果 T 为空或隐含的 对于 T 中的每一行 RT 为 False,则“R T”为False.",所以结果应该是False 你真的读过我的回答吗?它的运行状态不是数据的选择 db2 支持这种调试语法。使用相同条件选择记录将不会给出记录

以上是关于将常量与空集进行比较时,Db2 IN 谓词产生 NULL的主要内容,如果未能解决你的问题,请参考以下文章

const 与#define 的比较

使用 like 谓词(模式匹配)对 DB2 Z/oS 的 SQL 查询进行性能调优

将 NTEXT 列与常量值进行比较的正确方法是啥?

在 CloudKit 中使用比较谓词进行查询

如何在 Swift 中使用“IN”谓词进行 ckQuery?

CoreData:使用 IN 基于谓词/数组进行排序