前言:
今天在写一条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:结构
1 a
2 b
3 c
4 d
5 e
6 f
---------------------------------------------------------------------------------------------
表bb:结构
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,实现了,希望对大家有帮助。
分享到:
相关推荐
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
SQL Exporter did not export very old dates in date format - SQL Exporter could export floats with comma as decimal separator <br>PL/SQL Developer主要特性: PL/SQL编辑器,功能强大——该编辑器...
该特性提高了您编码的生产力,改善了PL/SQL代码的可读性,促进了大规模工作团队的协作。 SQL 窗口 该窗口允许您输入任何SQL语句,并以栅格形式对结果进行观察和编辑,支持按范例查询模式,以便在某个结果集合中...
实例17:列出库中欠缺编号-NOT IN 的应用(第8页71楼) 实例18:用 Union 从字段不相同的两个 Access 表中筛选记录后按相似字段排序(第11页102楼) 实例19:用 Union 进行忽略某种数值的汇总(第11页104楼)
该特性提高了您编码的生产力,改善了PL/SQL代码的可读性,促进了大规模工作团队的协作。 SQL 窗口——该窗口允许您输入任何SQL语句,并以栅格形式对结果进行观察和编辑,支持按范例查询模式,以便在某个结果集合中...
2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高) 分页存储过程:排序反转分页法 优化后的通用分页存储过程 sql语句 一些Select检索高级用法 SQL server 2005中新增的排序函数及应用 ...
数据查询语言 (Data Query Language, DQL) 是SQL语言中,负责进行数据查询而不会对数据本身进行修改的语句,这是最基本的SQL语句。例如:SELECT(查询) 数据控制语言Data Controlling Language(DCL),用来...
三 、数据存取对象变量对外来数据库编程的方法及其实例在VB专业版数据库编程的三种方法中,第二种-使用数据库存取对象变量(DAO)的方法最具有功能强大、灵活的特点。 它能够在程序中存取ODBC 2.0的管理函数;可以...
传统的静态网站己越来越不能满足现代社会发展的要求,采用基于AS P的动态网站技术来改变传统网站,已经成为改善可用性、降低管理成本和提升单位知识 平台的迫切需要。为实现单位信息化,下一代网站将广泛使用基于ASP...
使用类再生的两个方式:组合(new)和继承(extends),这个已经在 thinking in java中提到过. 设计模式之 Proxy(代理) 以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用...
1、测试流程管理、测试度量方法 按照尽早进行测试的原则,测试人员应该在需求阶段就介入,并贯穿软件开发的全过程。就测试过程本身而言,应该包含以s下几个阶段。 -测试需求的分析和确定。 -测试计划。 -...
provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. ------------------------...
三、在Windows XP Home版本中添加IIS的方法一般情况下按照“一”的方法只适用于Windows XP的专业版本,而对于家庭版,如今已有了破解方法:步骤1 首先我们需要准备一张Windows 2000的安装光盘,假设你的Windows XP...