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. SQL中EXISTS的用法(转)

    比如在Northwind数据库中有一个查询为SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID FR ...

  2. Android Studio之同一窗口打开项目

    Android Studio默认新打开的项目都是重新打开一个窗口,和原项目窗口同时存在,如果打开多个项目,则有很多窗口同时打开,怎么根据需要决定自己以何种方式打开呢? 1.设置打开新项目的方式 第一项 ...

  3. Oracle百问百答(一)

    Oracle百问百答(一) 01.如何查看oracle的版本信息? 02.如何查看系统被锁的事务信息? 03.怎么获取有哪些用户在使用数据库? 04. 数据表中的字段最大数是多少? 表或视图中的最大列 ...

  4. hdu4496 D-City

    D-City Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submis ...

  5. elf格式分析

    近期研究了一下elf文件格式,发现好多资料写的都比較繁琐,可能会严重打击学习者的热情,我把自己研究的结果和大家分享,希望我的描写叙述可以简洁一些. 一.基础知识 elf是一种文件格式,用于存储Linu ...

  6. C语言复合字面量的使用

    C99添加的特性,复合字面量(composite literal).一旦熟悉并使用,便会体会到简洁强大的表达. 所谓字面量就是固定数值的表示.数值和字符串类型都有字面量的表达.如: // 100, 1 ...

  7. Cocos3d初探

    预计要相当长的一段时间内研究游戏引擎,在这里做一下过程中的备忘. 上一周项目须要,研究了一下cocos2d-x,本周接着来做cocos3d-x的代码研究 首先是搭建cocos3d-x的开发环境: 依据 ...

  8. Fast portable non-blocking network programming with Libevent

    Fast portable non-blocking network programming with Libevent Fast portable non-blocking network prog ...

  9. HTML学习笔记——各种居中对齐

    0.前言     水平居中基本方法--指定块的宽度并设定块的左右外边距为auto,上下外边距可取0,那么该块能够在父元素中水平居中. 样式例如以下: 1:margin:0px auto 2:margi ...

  10. linux上svn连接visual svn server时ssl鉴权失败,问题解决(转)

    场景:1.在windows 7上安装了visual svn server作为自己的svn服务器. 2.在虚拟机centos 6.3上使用svn客户端check代码,报错: [plain] view p ...