当前位置:首页 > 开发 > 数据库 > 正文

在ORACLE语句中替换Not In 的方法

发表于: 2013-08-09   作者:bengben   来源:转载   浏览次数:
摘要:   前言: 今天在写一条sql查询语句,其需要从一个表A中返回所有A不再表B中的结果集,当然,这种实现最方便的方法就是用NOT IN。 如:select a.* from a where a.id not in (select id from b where…..) 我们大家都知道很多sql方面的文章都建议大家尽量不要使用NOT IN的方法,因为这种方法的效率不高
 

前言:

今天在写一条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   ……

1                                        a

2                                            b

3                                            c

4                                            d

5                                            e

6                                            f

---------------------------------------------------------------------------------------------

 

表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 where cc.tempcolum 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 where cc.tempcolum is null

我们只需要id和value两个字段,其他的就不要了。

结果

id  value

-------------------------

1     a        

3     c        

5           e        

 

ok,实现了,希望对大家有帮助。


原文出处:http://www.cnblogs.com/bbcw/archive/2005/02/04/101684.html

在ORACLE语句中替换Not In 的方法

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
当插入数据含有&时候,结果如下: 替换&sql如下,sql如'...&....'这种形式,如'test?rand=1234567&id
singleton实例依赖于prototype实例,ProtoType含义是无效的,必须钩入向Spring容器请求,也就是调用g
http://git.oschina.net/alexgaoyh/MutiModule-parent 代码此次变更较大,使用了mybatis-generator-
为了统一编码格式,需要将代码中的TAB替换成4个空格形式,由于文件很多,怎么能批量处理,经过探索
替换NSString类中的stringWithFormat:方法 先给出源码: YXUseful.h // // YXUseful.h // NSString /
  方式一:通过XQuery(需要SQL Server 2005以上版本)。   create function func_splitid oracle
戴上耳机,有音乐给你听... 昨天下午6:00给女朋友请安;6:10去马官营;22:45解决租房问题,赶回老
查看报名须知 报名网址: jlpt.etest.edu.cn 或 jlpt.etest.net.cn 2008年度日本语能力测试网上报名
使用已有的word 2007模版导出,常用的方法一般以下几种: (一)解压word模版后替换变量再压缩为word导
写在这篇文章之前:中文网页字体的窘境 在国外的设计师幸福地讨论着如何不用图片进行字体替换时,当
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号