3.5 集合运算 SQL
作用在关系上的union
、 intersect
和except
运算对应于数学集合论中的并(∪)、交(∩)和差(-)运算。我们现在来构造包含在两个集合上使用union
、 intersect
和except
运算的查询。
SQL
查询 在2009年秋季学期开设的所有课程的集合1 2 3 select course_idfrom sectionwhere semester = 'Fall' and year = 2009 ;
1 2 3 4 5 6 7 8 9 10 11 mysql> select course_id from section where semester ='Fall' and year=2009 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | +-----------+ 3 rows in set
SQL查询 在2010年春季学期开设的所有课程的集合 1 2 3 select course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> select course_id from section where semester='Spring' and year=2010 ; +-----------+ | course_id | +-----------+ | CS-101 | | FIN-201 | | MU-199 | | HIS-351 | | CS-319 | | CS-319 | | CS-315 | +-----------+
3.5.1 并运算 union 为了找出在200年秋季开课,或者
在2010年春季开课或两个学期都开课的所有课程,我们可写查询语句:
1 2 3 4 5 6 7 8 9 ( select course_id from section where semester = 'Fall' and year = 2009 )union ( select course_id from section where semester= 'Spring' and year = 2010 );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 mysql> ( select course_id from section where semester ='Fall' and year=2009 )union( select course_id from section where semester='Spring' and year=2010 ); +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | | FIN-201 | | MU-199 | | HIS-351 | | CS-319 | | CS-315 | +-----------+ 8 rows in set
有些SQL
实现不支持union
运算 尽管这是SQL-92
标准的一部分,但某些SQL
实现中可能不支持这种语法,经过我的测试MySQL
是支持union
运算的。
为便于阅读可将两条合并的查询放在括号中 上述SQL语句中我们在每条select-from- where
语句上使用的括号
是为了方便阅读,括号是可省略的
,也就是说写成如下形式也是可以的:
1 2 3 4 5 6 7 select course_idfrom sectionwhere semester = 'Fall' and year = 2009 union select course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 mysql> select course_id from section where semester ='Fall' and year=2009 union select course_id from section where semester='Spring' and year=2010 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | | FIN-201 | | MU-199 | | HIS-351 | | CS-319 | | CS-315 | +-----------+ 8 rows in set
union运算会自动去除重复 与select
子句不同, union
运算自动去除重复。
union all运算会保留重复 如果我们想保留所有重复,就必须用union all
代替unIon
:
1 2 3 4 5 6 7 select course_idfrom sectionwhere semester = 'Fall' and year = 2009 union all select course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 mysql> select course_id from section where semester ='Fall' and year=2009 union all select course_id from section where semester='Spring' and year=2010 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | | CS-101 | | FIN-201 | | MU-199 | | HIS-351 | | CS-319 | | CS-319 | | CS-315 | +-----------+ 10 rows in set
3.5.2 交运算 intersect SQL
查询 找出在2009年秋季和2010年春季同时开课的所有课程的集合1 2 3 4 5 6 7 select course_idfrom sectionwhere semester = 'Fall' and year = 2009 intersect select course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
保留重复intersect all intersect
运算自动去除重复。如果我们想保留所有重复,就必须用intersect all
代替intersect
:
MySQL
不支持intersect运算经过我的测试MySQL
好像不支持intersect
运算符,所以MySQL
中得通过其他方式实现交
运算。
MySQL
中通过union运算实现交运算原理就是求table1与table2不去除重复条目的并集,然后按想要的属性分组,取其中重复条目
1 2 3 4 5 6 7 8 9 10 select * from ( select course_id from section where semester = 'Fall' and year = 2009 union all select course_id from section where semester= 'Spring' and year = 2010 ) S group by course_id having count (* )> 1 ;
由于这种方式还有一个条件是table1
和table2
中各自不能有重复值
,不然结果不正确,所以查询的时候需要使用select distinct
先取出重复值.
SQL
查询 找出在2009年秋季所有课程的集合1 2 3 select distinct course_idfrom sectionwhere semester = 'Fall' and year = 2009 ;
SQL
查询 找出在和2010年春季开课的所有课程的集合1 2 3 select distinct course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
SQL
查询 找出在2009年秋季和2010年春季同时开课的所有课程的集合1 2 3 4 5 6 7 8 9 10 11 select * from ( select distinct course_id from section where semester = 'Fall' and year = 2009 union all select distinct course_id from section where semester= 'Spring' and year = 2010 ) S group by course_id having count (* )> 1 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 mysql> select distinct course_id from section where semester ='Fall' and year=2009 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | +-----------+ 3 rows in set mysql> select distinct course_id from section where semester='Spring' and year=2010 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-315 | | CS-319 | | FIN-201 | | HIS-351 | | MU-199 | +-----------+ 6 rows in set mysql> select * from ( select distinct course_id from section where semester ='Fall' and year=2009 union all select distinct course_id from section where semester='Spring' and year=2010 ) S group by course_id having count(*)>1 ; +-----------+ | course_id | +-----------+ | CS-101 | +-----------+ 1 row in set
3.5.3 差运算 except SQL查询 找出在2009年秋季学期开课但不在2010年春季学期开课的所有课程 1 2 3 4 5 6 7 select course_idfrom sectionwhere semester = 'Fall' and year = 2009 except select course_idfrom sectionwhere semester= 'Spring' and year = 2010 ;
except
运算从其第一个输入中输出所有不出现在第二个输人中的元组
保留重复except all except
运算在执行集差操作之前自动去除输入中的重复,如果我们想保留所有重复,就必须用except all
代替except
:
Oracle使用minus代替except 某些SQL
实现,特别是Oracle
,使用关键词minus
代替except
。
MySQL
不支持except
运算符MySQL
中通过not in
实现差运算1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 mysql> select course_id from section where semester ='Fall' and year=2009 ; +-----------+ | course_id | +-----------+ | CS-101 | | CS-347 | | PHY-101 | +-----------+ 3 rows in set mysql> select course_id from section where semester='Spring' and year=2010 ; +-----------+ | course_id | +-----------+ | CS-101 | | FIN-201 | | MU-199 | | HIS-351 | | CS-319 | | CS-319 | | CS-315 | +-----------+ 7 rows in set mysql> select course_id from section where semester ='Fall' and year=2009 and course_id not in ( select course_id from section where semester='Spring' and year=2010 ); +-----------+ | course_id | +-----------+ | CS-347 | | PHY-101 | +-----------+ 2 rows in set
参考链接 https://blog.csdn.net/qq_39023116/article/details/79008085 https://www.w3cschool.cn/mysql/mysql-vge12oye.html