not exists 和 not in 查询结果不一致的原因

SQL>create table test1(a number);
SQL>create table test2(b varchar2(20));
SQL>insert into test1 select object_id from user_objects;
SQL>insert into test2 select object_id from user_objects;
SQL>update test2 set b = null where b  >70000;

SQL>select count(1) from test1 t1 where not exists
(select 1 from test2 t2 where t1.a=t2.b);

  COUNT(1)
----------
       110

SQL>select count(1) from test1  where a not in
(select b from test2);

  COUNT(1)
----------
         0

      看似相同的语义实质查询的结果不一致,原因是单列的NULL,如果非相关子查询的结果有NULL,那么整个条件为,FALSE/UNKNOWN,也就是没有结果的原因,如果深入分析下,等价于SELECT .... WHERE ID <> NULL AND ID <>....根据NULL的比较和逻辑运算规则,可以知道整个条件要么是false,要么是unknown,所以没有结果。

       多说一句,IN子查询相当于OR条件,根据NULL的逻辑运算规则,哪个条件为TRUE的行就返回那个行。


通过10053事件跟踪得出以上的语句转换

not exists:

SELECT COUNT(*) "COUNT(1)"
  FROM "TEST"."TEST2" "T2", "TEST"."TEST1" "T1"
 WHERE "T1"."A" = TO_NUMBER("T2"."B");
not in:
SELECT COUNT(*) "COUNT(1)"
  FROM "TEST"."TEST1" "SYS_ALIAS_1"
 WHERE NOT EXISTS
 (SELECT /*+ */ 0 FROM "TEST"."TEST2" "TEST2"
         WHERE LNNVL(TO_NUMBER("TEST2"."B") <> "SYS_ALIAS_1"."A"));

注:lnnvl用于某个语句的where子句中的条件,如果条件为true就返回false;如果条件为UNKNOWN或者false就返回true。该函数不能用于复合条件如AND, OR, or BETWEEN中。

根据10053事件可以推导出,如果一定要用not in,可以改写为

SQL> select count(1) from test1
      where a not in (select b from test2 where test1.a=test2.b);
 
  COUNT(1)
----------
       110


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在ive中,如果我们使用的版本不支持类似于in、exists、not in等子查询,很可能是0.13版本之前的旧版本。在这种情况下,我们可以将not in改写为not exists来实现相同的功能。具体的改写方法可以参考以下示例查询语句: SELECT * FROM test.in_test1 test1 WHERE NOT exists (SELECT * FROM test.in_test2 test2 WHERE test1.name = test2.name)。 此外,如果在使用Hive的过程中遇到无法查询出结果的情况,主要原因可能是因为Hive不支持where子句中的子查询。因此,需要将not in的SQL语句改写为not exists或left join来解决这个问题。可以参考以下示例创建表、插入数据和查询数据的操作: 1. 创建表: CREATE TABLE test.in_test1 (id varchar(10), name varchar(10), sex varchar(10), age varchar(10)); CREATE TABLE test.in_test2 (id varchar(10), name varchar(10), class varchar(10), school varchar(10)); 2. 插入数据: INSERT INTO test.in_test1 VALUES ('1', 'xiaoming', '1', '17'), ('2', 'xiaohua', '0', '23'), ('3', 'jack', '1', '12'), ('4', 'rose', '0', '28'), ('5', 'jenny', '0', '45'), ('6', 'judy', '0', '10'), ('7', 'wangwu', '1', '35'); INSERT INTO test.in_test2 VALUES ('1', 'xiaoming', '3', '花花高中'), ('2', 'xiaohua', '5', '北京大学'), ('3', 'jack', '2', '新民中学'), ('4', 'rose', '1', '清华大学'); 3. 查询数据: SELECT * FROM test.in_test1; 这样,你就可以在Hive中使用not in相关的查询了。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值