SQL-3标准中提供了三种对检索结果进行集合运算的命令:并集UNION;交集INTERSECT;差集EXCEPT(在Oracle中叫做 MINUS)。在有些数据库中对此的支持不够充分,如MySql中只有UNION,没有其他两种。实际上这些运算都可以通过普通的SQL来实现,虽然有时有些繁琐。

假设有两个表(或视图)s,t,s中有两个字段sa,sb;t中有两个字段ta,tb;

差集EXCEPT:

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. EXCEPT
  3. SELECTtaFROMt;

可以写作

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. WHEREsaNOTIN
  3.    (SELECTtaFROMt)

上面的例子中忽略了对s和t单独的条件,这些总可以加入AND条件完成,或者使用视图。如果是多个字段比较麻烦,如:

PLAIN TEXT
SQL:

  1. SELECTsa, sbFROMs
  2. EXCEPT
  3. SELECTta, tbFROMt;

需要写成

PLAIN TEXT
SQL:

  1. SELECTsa, sbFROMs
  2. WHERE(sa, sb)NOTIN
  3.    (SELECTta, tbFROMt)

上面使用的语法不见得数据库都支持。好在不支持EXCEPT的MySQL支持这种语法,而不支持这种语法的MSSQL又支持EXCEPT。

注意对于这样的row constructors(Mysql术语),是和下面写法(以及其他类似写法)不等价的。

PLAIN TEXT
SQL:

  1. SELECTsa, sbFROMs
  2. WHEREsaNOTIN
  3.    (SELECTtaFROMt)
  4. ANDsbNOTIN
  5.    (SELECTtbFROMt)

在MSSQL中的一个解决技巧是,把这两个字段(假设字符类型)拼起来,即

PLAIN TEXT
SQL:

  1. SELECTsa, sbFROMs
  2. WHEREsa+sbNOTIN
  3.    (SELECTta+tbFROMt)

交集INTERSECT:

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. INTERSECT
  3. SELECTtaFROMt;

可以写成

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. WHEREsa IN
  3.    (SELECTtaFROMt)

当然也可以写成

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. WHEREEXISTS
  3.    (SELECT*FROMtWHEREt.ta=s.sa)

或者使用连接

PLAIN TEXT
SQL:

  1. SELECTsaFROMs, t
  2. WHEREsa = ta

实际上这几个语句都有点问题,就是INTERSECT在出现重复时的语义问题。按照SQL-3标准,类似UNION,可以有明确的
INTERSECT ALL或者INTERSECT
DISTINCT语法。一般的INTERSECT实现并没有明确这一点,而且从逻辑上讲意义也不大。那么当s或t中出现重复的时,如sa='x'的有2
个,sb='x'的有3个,使用上面的子查询将返回2行,使用连接将返回6行,当然这两个语句都可以加上一个DISTINCT,就实现了
INTERSECT DISTINCT语义了。

并集UNION:

MySql从4.0开始就支持UNION(ALL 和 DISTINCT)了,为完整起见,也列举一下。
其实实现这样一个结果是很麻烦的

PLAIN TEXT
SQL:

  1. SELECTsaFROMs
  2. UNIONDISTINCT
  3. SELECTtaFROMt;

需要使用外连接,而且是Full的外连接

PLAIN TEXT
SQL:

  1. SELECTDISTINCTNVL(s.sa, t.ta)
  2. FROMs FULLOUTERJOINtON(s.sa=t.ta)

上面的例子中我使用了Oracle的语法,实际上MySql不支持FULL OUTER JOIN(虽然支持LEFT和RIGHT OUTER JOIN),好在MySql支持UNION。

对于UNION ALL语义,我还没有想出来用普通查询如何实现,如果在上面语句中去掉DISTINCT,结果肯定不对。

SQL集合运算 差集 并集 交的更多相关文章

  1. 集合运算—union(并集)、intersect(交集)和except(差集)

    一.集合运算的基本格式是: 集合查询1 <集合运算> 集合查询2 [order by ...] 二.集合运算符是对两个集合操作的,两个集合必须具有相同的列数,列具有相同的数据类型(至少能隐 ...

  2. 详解SQL集合运算

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...

  3. 7 SQL 集合运算

    7 集合运算 7-1 表的加减法 本章将会和大家一起学习“集合运算”操作.在数学领域,“集合”表示“(各种各样的)事物的总和”:在数据库领域,表示“记录的集合”.具体来说,表.视图和查询的执行结果都是 ...

  4. SQL集合运算参考及案例(一):列值分组累计求和

    概述 目前企业应用系统使用的大多数据库都是关系型数据库,关系数据库依赖的理论就是针对集合运算的关系代数.关系代数是一种抽象的查询语言,是关系数据操纵语言的一种传统表达方式.不过我们在工作中发现,很多人 ...

  5. SQL集合运算:差集、交集、并集

    1.差集( except ) select a from t_a except select a from t_b -- 也可写作: select a from t_a where a not in ...

  6. python 集合运算交集&并集&差集

    差集>>> #两个列表的差集3 >>> ret3 = list(set(a) ^ set(b)) #两个列表的差集 >>> ret4=list(s ...

  7. 【python】集合 list差集|并集|交集

    两个list差集 list(set(b).difference(set(a))) # b中有而a中没有的 示例: a=[1,2,3] b=[2,3] list(set(a).difference(se ...

  8. sql 集合运算

    UNION 并运算 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每条 SE ...

  9. SQL集合运算参考及案例(二):树形节点数量逐级累计汇总

    问题描述: 我们经常遇到这样一个问题,类似于面对一个树形结构的物料数据,需要将库存中每一种物料数量汇总到物料上展示出来:或者说组织机构是一棵树,我们需要统计每一个节点上的人员数量(含下级节点的累计数量 ...

随机推荐

  1. java 显示目录下全部文件

    package gao.org; import java.awt.HeadlessException; import java.io.File; import javax.swing.JFileCho ...

  2. [置顶] 深圳华为BSS公共部件 (BI 商业智能 Java Javascript)

    深圳华为BSS公共部件 部门招聘 招聘面试地点:大连,西安 工作地点:深圳 时间:2013年9月7日 联系方式:dawuliang@gmail.com 18675538182 有兴趣的同学,可以直接电 ...

  3. linux 软连接 硬连接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接] 硬连接指通过索引 ...

  4. 主流JavaScript框架(Dojo、Google Closure、jQuery、Prototype、Mootools和YUI)的分析和对比

    本文主要选取了目前比较流行的JavaScript框架Dojo.Google Closure.jQuery.Prototype.Mootools和YUI进行对比,主要是根据网上的资料整理而成,希望可以供 ...

  5. Shell脚本检查memcache进程并自己主动重新启动

    修正版: #!/bin/sh #check memcache process and restart if down mm_bin="/usr/local/bin/memcached&quo ...

  6. Xcode如何添加字体库--

    1.网上搜索字体文件(后缀名为.ttf,或.odf) 2.把字体库导入到工程的resouce中 3.在程序viewdidload中加载一下一段代码 NSArray *familyNames = [UI ...

  7. SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge (并不在同一个版本库中)

    在使用svn merge命令报错 英文版本:SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge 中文版本报错:并不 ...

  8. cpe移植framework后,。解决问题的现有数据库

    最近,该公司的业务需求,原始订单apk的形式CPE.渗透framework层.这被剥离cpe,从事相当长的一段,终于有时间来写博客,记下遇到的问题,未来. 第一个问题是,原来的apk有些事情,移植fr ...

  9. ActiveMQ源码架构解析第一节(转)

    工作四年已久,也快到了而立之年,本人也酷爱技术,总是想找一些途径来提升自己,想着温故而知新所以就写起了博客,然而写博客这个想法也是酝酿了很久,近期也看到了有很多人在问关于ActiveMQ的相关问题,有 ...

  10. SVN的svnlook命令

    svnlook命令集(zhuanzai) 2011-12-08 17:00:30|  分类: System and CVS|字号 订阅     svnlook 名称 svnlook author — ...