暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如下SQL语句SELECT * FROM t t1 WHERE t1.a not in (SELECT b FROM t t2);是否可以重写

openGauss小助手 2021-10-31
1072

问题描述

如下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。
    图片.png
    则第一句的执行结果为:
    图片.png
    即该类情况下第一句不会输出与NULL对应的元组。对于第二句,不是SQL支持的JOIN,无法通过直接执行SQL检验。但根据anti join的语义,可知此时执行结果会输出NULL。
  • 若a中无NULL而b中有NULL,即考虑如下关系t。
    图片.png
    则第一句的执行结果为:
    图片.png
    即该情形下第一句不会输出与NULL对应的元组。对于第二句,可知执行结果会输出与NULL对应的元组。
  • 若a中有NULL且b中有NULL,即考虑如下关系t。
    图片.png
    则第一句的执行结果为:
    图片.png
    同上,此情形下两句执行结果不一致。
    综上,需要在第二句中加入对NULL的处理,故补入条件or t1.a is NULL or t2.b is NULL。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论