在sql语句中替换NotIn的⽅法
前⾔:
今天在写⼀条sql查询语句,其需要从⼀个表A中返回所有A不再表B中的结果集,当然,这种实现最⽅便的⽅法就是⽤NOT IN。
如:
select a.*from a where a.id not in(select id from b where…..)
我们⼤家都知道很多sql⽅⾯的⽂章都建议⼤家尽量不要使⽤NOT IN的⽅法,因为这种⽅法的效率不⾼。那有没有替代的办法呢?(声明因为当时的情况要求不能使⽤储存过程,所以只有写sql语句)和同事实验了⼀下,结果⽤以下⽅法实现了。
⽬的:
替换NOT IN ⽅法。
说明:
在单条SQL语句中,不使⽤储存过程,不使⽤临时表。使⽤存储过程和临时表不再本⽂的讨论范围中。
实现:
例:
表aa:结构
id value
1a
2b
3c
4d
5e
6f
表bb:结构
id…
2
4
6
现在我要取表aa⾥的所有字段,条件是aa的id值不在bb的id值当中(not in)。也就是应该返回所有id为奇数的字段
使⽤NOT IN的SQL:
select*from aa where id not in(select id from bb)
就⼀条语句,简单明了,可惜效率不⾼,⽽且公司规范要求尽量不⽤NOT IN,害我费了好⼤事crying……
改造后的SQL:
select cc.id,cc.value from(select aa.*,bb.id as tempcolum from aa left join bb on aa.id=bb.id)as cc pcolum is null
解释⼀下。在开始时候我最早想⽤内联表的⽅式,可是⽆论如何也每到⼀个好的办法,⼲脆就是实现不了。(⼤家有好办法指教先。)
后来⾃⼰考虑了⼀下NOT IN的逻辑,A NOT IN B就是说A是主体,B起到的之不过是⼀个判断作⽤,我们可以先把所有符合条件的A记录全部查询出来⽽不管他是否属于B,然后再从这⾥剔除值同时属于B的部分。
Select aa.*from aa
但是仅仅这样是不够的,我们⽆法利⽤这个返回的结果集判断是否属于B并排除它,为此,我想到构造⼀个临时的列,这个列的值应该是在A的结果集范围内,所有在B中的值。⽽这个结果集的主体应该是所有满⾜先决条件的A,然后加上满⾜条件的B,⽽不满⾜条件的B值则不再考虑范围内,所以⽤了left join。
这⼀段是关键,不知道我阐述清楚了没有,没明⽩的继续看
于是就出来这⼀句。
select aa.*,bb.id as tempcolum from aa left join bb on aa.id=bb.id
没看明⽩上⾯的看结果集就明⽩了
id value tempcolum
1 a NULL
2 b 2
3 c NULL
4 d 4
5 e NULL
6 f 6
看到这个结果集我想⼤家都明⽩我的意思了吧。对了,我们就是要对这个结果集进⾏⼆次操作。
相信⼤家都看到了,⽣成的这个结果集包含了所有符合条件的表aa字段和bb的id,如果aa中的值在bb
中,则tempcolum的值就不会为null,如果不在就是null,这样我们只需要从这个结果集⾥查询所有tempcolum值为null的就可以满⾜我们的要求了
所以最终的sql出来了
select cc.id,cc.value from(select aa.*,bb.id as tempcolum from aa left join bb on aa.id=bb.id)as cc pcolum is null
我们只需要id和value两个字段,其他的就不要了。
结果
id value
1 a
3 c
5 e
sql语句替换表中内容ok,实现了,希望对⼤家有帮助。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论