Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询

一、集合操作

1.UNION:并集运算。

语法结构:

SQL>select 表1的列1, 表1的列2 from 表1 union select表2的列1, 表2的列2 from表2;


其中表1的列1和表1的列2是来自于表1的两列,表2的列1和表2的列2是来自于表2的两列,需要注意的是,如果union前面是n列,那么后面也必须是n列,即union前后列数必须相同。而且查询结果的列名是按照union前面n列的名称命名(如例1)。

 

2.INTERSECT:交集运算。

语法结构:

SQL>select empno, ename from emp intersect select empno, ename from emp where sal > 1500;


intersect前面是对emp表全查,后面是对emp表有选择的查询,那么前后取交集就是筛选出emp表满足sal>1500条件的员工信息。

 

3.MINUS:找出两个给定集合之间的差异。

语法结构:

SQL>selecte empno, ename from emp minus select empno,ename from emp where sal > 1500;


即去掉相同的部分。

 

1:练习集合运算union。

解:当前student表数据:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第1张图片

当前course表数据:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第2张图片

将sno, sname,cno, cname取并集:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第3张图片

如果union前后列数不一样,会报错:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第4张图片


2:练习交集运算intersect。

解:先查看student表和course表:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第5张图片

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第6张图片

取两者交集:


因为没有交集,所以显示“未选定行”。

 

3:继续交集运算intersect。

解:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第7张图片

intersect前面是对student表全查,后面是查出sno>’s005’的数据,那么前后取交集,结果如上图所示。

如果这时候对于student表和sc表取交集:


其中sc表数据:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第8张图片

交集运算没结果,是因为intersect前面列名和后面列名要相同,本例中前面sno和sname,后面sno和cno,不一样,所以交集无结果。


4:练习差集运算minus。

解:对于student表,刨除sno<’s005’部分:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第9张图片

 

二、子查询

到目前位置介绍查询语句都只包含一条SELECT语句。

 

1.子查询的基本类型:

1)单行子查询:不向外部的SQL语句返回结果,或者只返回一行;

①where子句中可使用单行子查询,即子查询可以放在另外一个查询的where子句中;(总结:where关键字后可用单行子查询)

比如:查询小于整个员工平均工资的员工信息。

SQL>select empno, ename from emp where sal <(select avg(sal) from emp);

 

②having子句中可使用单行子查询。(总结:having关键字后可用单行子查询)

比如:查询哪些职位的平均工资大于整个员工的平均工资。

SQL>select job, avg(sal) from emp group by job

       2 having avg(sal) >(select avg(sal) from emp);

 

③from子句中可使用单行子查询,这种子查询称为内联视图。(总结:from关键字后可用单行子查询)

比如:查询哪些员工的工资高于所任职位的平均工资,就是比如a员工是IT行业,其工资15000大于IT行业平均工资8000,那么就把这个a员工查出来,如果b员工工资1200小于其行业平均工资1500,那么查询结果中就不包含b员工……


SQL>select ename, sal, b.c from emp a,(select job,avg(sal) c from emp group by job) b where a.sal > b.c and a.job =b.job;


其中a,b,c是别名,(select job, avg(sal) c from emp group by job)是子查询,查出每个行业的平均工资,后面where判断a.sal是员工工资,b.c是行业平均工资。

 

2)多行子查询:向外部的SQL语句返回一行或多行;

3)多列子查询;

4)关联子查询;

5)嵌套子查询。

 

5:练习子查询(对应:二-1-(1)-①)

解:基于现有的student表,查询小于整个学生平均年龄的学生学号和姓名。

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第10张图片

上图中,where中有子查询,即查询出当前学生表中的平均年龄,然后如果sage<平均年龄,符合条件,在查询结果中显示。

where后面的子查询是供外部select使用的查询。

【注意】以下这种语法错误:

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第11张图片

因为聚合函数是要由select语句显示结果,这么直接用是错误的。

 

6:练习子查询(对应:二-1-(1)-②)

解:查询某些课程的平均成绩,要求该成绩大于所有学生成绩的平均分。

Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询_第12张图片

对于上图中的命令有如下说明:

(1)group by cno是将表中数据按照cno相同的分为一组,即同一门课程为一组;

(2)having子句用了子查询,即(select avg(score) from sc)可以查到sc表score列所有数据的均值,即所有学生成绩的均分;

(3)先select查询到每门课程的均分avg(score)后,去having子句判断是否满足条件,若满足条件,则在查询结果中显示。

【切记】子查询不能包含排序,即不能包含group by子句。

你可能感兴趣的:(Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询)