用SQL表达交并差操作

交-并-差的处理

  • SQL语言:并运算UNION,交运算INTERSECT,差运算EXCEPT
  • 基本语法形式:
子查询{UNION [ALL] | INTERSECT [ALL] | EXPECT [ALL] 子查询}
  • 通常情况下自动删除重复元组:不带ALL。若要保留重复的元组,则要带ALL

示例1:求即学过Math课程,又学过English课程的同学
表结构

SELECT * FROM SC
+----------------+------------------+
| name           | course           |
+----------------+------------------+
| Tom            | English          |
| Tom            | Math             |
| David          | english          |
| David          | Computer         |
+----------------+------------------+

查询

SELECT name FROM SC WHERE course = 'Math'
INTERSECT
SELECT name FROM SC WHERE course = 'English';

注意!Mysql4.0中增加了对UNION的支持,但是仍然不支持INTERSECTEXPECT

这是因为交运算符INTERSECT并没有增强SQL的表达能力。没有INTERSECT,SQL也可以通过其他方式表达同样的查询需求。只是有了INTERSECT更容易表达一些.。但是增加了SQL语言的不唯一性。

比如上面的查询可以用如下方式替换

SELECT name FROM sc WHERE course='Math' AND name IN
(SELECT name FROM sc WHERE course='English')
+----------------+
| name           |
+----------------+
| Tom            |
+----------------+

示例2:假定所有学生都有选课,求没有学过Math课程的学生
不能写成

SELECT name FROM sc WHERE course<>'Math'

可以写成

SELECT name FROM sc
EXCEPT
SELECT name FROM sc WHERE course='Math'

同样的EXCEPT也没有增强SQL的表达能力,上面的查询可以改写为

SELECT DISTINCT name 
FROM sc sc1
WHERE NOT EXISTS 
(
    SELECT name 
    FROM sc 
    WHERE course='Math' 
        AND name = sc1.name
)
+----------------+
| name           |
+----------------+
| David          |
+----------------+

注意

  • UNION运算符是Entry-SQL92的一部分
  • INTERSECTEXCEPTFull-SQL92的一部分
  • 它们都是Core-SQL99的一部分,但有些DBMS并不支持这些运算
posted @ 2019-03-19 11:18  Velscode  阅读(1131)  评论(0编辑  收藏  举报