问题描述
如下SQL语句SELECT * FROM t t1 WHERE t1.a not in (SELECT b FROM t t2);是否可以重写为:SELECT * FROM t t1 (anti join) (SELECT b FROM t t2) t2 on t1.a = t2.b;
专家解答
知识点:子查询提升,NULL的等价变化。
答案:否。
解决方案:在第二句中补入条件or t1.a is NULL or t2.b is NULL。
题目解析:该题的问题出现在对NULL的处理上,我们分别考虑以下三种情形:
- 若a中有NULL而b中无NULL,即考虑如下关系t。

则第一句的执行结果为:

即该类情况下第一句不会输出与NULL对应的元组。对于第二句,不是SQL支持的JOIN,无法通过直接执行SQL检验。但根据anti join的语义,可知此时执行结果会输出NULL。 - 若a中无NULL而b中有NULL,即考虑如下关系t。

则第一句的执行结果为:

即该情形下第一句不会输出与NULL对应的元组。对于第二句,可知执行结果会输出与NULL对应的元组。 - 若a中有NULL且b中有NULL,即考虑如下关系t。

则第一句的执行结果为:

同上,此情形下两句执行结果不一致。
综上,需要在第二句中加入对NULL的处理,故补入条件or t1.a is NULL or t2.b is NULL。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




