复合列的not in的问题

create table t1(a number,b number);
create table t2(a number,b number);
insert into t1 values(1,1);
insert into t1 values(1,2);
insert into t2 values(1,1);
insert into t2 values(null,2);
commit;

--同样,查询t1的(a,b)同时满足不在t2表中的记录
SQL> select * from t1
  2   where (a,b) not in (select a,b from t2);

         A          B
---------- ----------

--同样用相关子查询改写则正确,结果省略
select * from t1
where (a,b) not in (select a,b from t2 where t1.a=t2.a and t1.b=t2.b);
select * from t1
where   not exists (select 1 from t2 where t1.a=t2.a and t1.b=t2.b);

----分析如下:因为是复合列,相当于列的组合条件是or,只要有一个列不满足条件,就应该返回那个记录

--数据改变下
SQL> delete from t2 where a is null;
SQL> insert into t2 values(null,3);
SQL> commit;
SQL> select * from t1
  2   where (a,b) not in (select a,b from t2);

         A          B
---------- ----------
         1          2

--用前面的分析改写,等价于上面的语句
SQL> select * from t1
  2   where (a <> null or b <> 3)
  3  and (a <>1 or b <> 1);

         A          B
---------- ----------
         1          2

/**
根据NULL的比较和逻辑运算规则,OR条件有一个为TRUE则返回TRUE,全为FALSE则结果为FALSE,其他为UNKNOWN,比如
(1,2) not in (null,2)则相当于1 <> null or 2 <> 2,那么明显返回的结果是UNKNOWN,所以不可能为真,不返回结果,但是
(1,2) not in (null,3)相当于1 <> null or 2 <> 3,因为2<>3的已经是TRUE,所以条件为TRUE,返回结果,也就说明了为什么测试是那样的结果
**/

看个简单的结果:
SQL> SELECT * FROM DUAL WHERE (1,2) not in ( (null,2) );

DUMMY
-----
SQL> SELECT * FROM DUAL WHERE (1,2) not in ( (null,3) );

DUMMY
-----
X

转自:http://www.itpub.net/thread-1325582-1-1.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值