Oracle数据库学习笔记7——PL/SQL高级查询-集合查询

复习:数据库的五个基本运算

选择

在这里插入图片描述

投影

在这里插入图片描述

连接

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

集合查询

集合查询将两个或多个SQL语句的查询结果集合并起来,利用集合进行查询处理以完成特定的任务
使用四个集合操作符(Set Operator)UNIONUNION ALLINTERSECTMINUS,将两个或多个SQL查询语句结合成一个单独SQL查询语句。

集合操作符的功能:
在这里插入图片描述

集合查询的基本语法如下:

语法格式:

<SELECT查询语句1>
{UNION | UNION A LL | INTERSECT | MINUS}
<SELECT查询语句2>

说明:

在集合查询中,需要遵循的规则为:
● 在构成复合查询的各个单独的查询中,列数和列的顺序必须匹配,数据类型必须兼容。
●用户不许在复合查询所包含的任何单独的查询中使用ORDER BY子句
● 用户不许在BLOB、LONG等大数据对象上使用集合操作符
●用户不许在集合操作符SELECT列表中使用嵌套表或者数组集合。

使用UNION操作符(并)

UNION语句将第一个查询中的所有行与第二个查询的所有行相加,消除重复行并且返回结果。

与连接的区别:连接是把列合在一起,并是把行合在一起(行要能合在一起就要求有相同的列)

【例1】查询性别为女及选修了课程号为4002的学生。

SELECT sno, sname, ssex
  FROM student
  WHERE ssex='女'
UNION
SELECT a.sno, a.sname, a.ssex 
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

在这里插入图片描述
【例2】查询所有女教师和女学生的姓名、性别和出生日期。

SELECT tname, tsex, tbirthday
  FROM teacher
  WHERE tsex='女'
UNION
SELECT sname, ssex, sbirthday
  FROM student
  WHERE ssex='女';

使用UNION ALL操作符

UNION ALL语句与标准的UNION语句工作方式基本相同,唯一不同的是UNION ALL不会从列表中滤除重复行。

【例】查询性别为女及选修了课程号为4002的学生,不滤除重复行。

SELECT sno, sname, ssex
  FROM student
  WHERE ssex='女'
UNION ALL
SELECT a.sno, a.sname, a.ssex 
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

在这里插入图片描述
(查询结果与上例1比较)

使用INTERSECT操作符(交)

INTERSECT操作会获取两个查询,对值进行汇总,并且返回同时存在于两个结果集中的行。只由第一个查询、或者第二个查询返回的那些行不包含在结果集中。

【例1】查询既选修了课程号为8001又选修了课程号为4002的学生的学号、姓名、性别。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='8001'
INTERSECT
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

(找出分别符合两个条件的两个集合,取交集,得到两个条件都符合的)

但是不能直接写成 WHERE a.sno=b.sno AND b.cno='8001' AND b.cno='4002'; 因为学号不可能同时既是8001又是4002

(这个要会)【例2】查询既选修了课程名含有”数据库”又选修了课程名含有”数学”且性别为”男”的学生的学号、姓名、性别和班号。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname like '%数据库%' AND a.ssex='男'
INTERSECT
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname like '%数学%' AND a.ssex='男';

使用MINUS操作符(差)

MINUS集合操作会返回所有从第一个查询中有但是第二个查询中没有的那些行。

【例1】查询既选修了课程号为8001又未选修课程号为4002的学生的学号、姓名、性别。

SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='8001'
MINUS
SELECT a.sno AS 学号, a.sname AS 姓名, a.ssex AS 性别
  FROM student a, score b
  WHERE a.sno=b.sno AND b.cno='4002';

(找出分别符合两个条件的两个集合,取差集,得到符合第一个条件不符合第二个条件的)

【例2】查询既选修了英语又未选修数字电路的学生的姓名、性别、出生日期和班号。

SELECT a.sname AS 姓名, a.ssex AS 性别, a.sbirthday AS 出生日期, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname='英语' 
MINUS
SELECT a.sname AS 姓名, a.ssex AS 性别, a.sbirthday AS 出生日期, a.sclass AS 班号
  FROM student a, course b, score c
  WHERE a.sno=c.sno AND b.cno=c.cno AND b.cname='数字电路';

强调:做集合查询,列数和列的顺序必须匹配,数据类型必须兼容,因为是做行的运算

猜你喜欢

转载自blog.csdn.net/weixin_45550460/article/details/105180088