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的extends使用方法

    理解继承是理解面向对象程序设计的关键.在Java中,通过keywordextends继承一个已有的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类).在Java中不同意多继承. (1)继承 ...

  2. Urxvt - awesome

    Urxvt - awesome Urxvt From awesome Jump to: navigation, search rxvt-unicode (urxvt for short) is a c ...

  3. Linux命令之rz - 批量上传文件,简单易用(转载)

    用途说明 rz命令能够批量上传文件,当然也可上传单个文件啦.使用的协议是古老的ZMODEM协议,尽管协议古老,但毫不影响的简单易用的特性.一般情 况我们要上传文件到Linux系统,要么使用ftp(还得 ...

  4. 安卓开发28:自定义View类

    自定义View类 通过自定义View类,可以自定义复杂的,按照自己需求的控件. 一个简单的例子 mainActivity.java 这个里面就是最普通的代码,但是给自定义的控件加上了一个onclick ...

  5. g++编C++11/C++0x遇到的问题

    在看<Cplusplus Concurrency In Action Practical Multithreading>当遇到第一个样品: #include<iostream> ...

  6. Do you master on array in C ?

    Do you master on array in C ? 因为新标准C99的支持变长数组, 差点儿C的标准特性就是看着gcc来的(Linux 内核严重依赖GCC) int mani() { cons ...

  7. Apache配置虚拟文件夹

    作为一个Android开发人员,一直以为,至少应该有一个server语言,最近慢慢学习php,当然学习Apache使用.本文介绍Win7环境下,怎样配置Apache的虚拟文件夹. 首先,找到我们Apa ...

  8. inkscape - 百度百科

    http://wapbaike.baidu.com/view/1267893.htm?ssid=0&from=844b&uid=3151E6C0905477A13653132D762B ...

  9. Oracle 数据迁移(从Oracle11G迁移到更高的版本号Oracle10G低版本号)

    1.数据库状况    生产环境是11G,linux系统,測试环境是10G,windows系统,须要从生产环境导出一个用户下全部的数据,导入測试环境中. 由于数据量比較小,准备採用EXP和IMP工具来做 ...

  10. C/S与B/S谁与争锋之我见

    看到网上有些人在讨论C/S架构和B/S架构以及它们的发展趋势,后起之秀B/S是否真将取代C/S而存在?在发表我的观点之前,我们先来一起来回顾下C/S以及B/S. 一C/S 1.C/S概念 C/S是Cl ...