Oracle子查询:where/from/having子查询
最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!
我要咨询一般情况下:
WHERE:子查询一般只返回单行单列、多行单列、单行多列的数据;
FROM:子查询返回的一般是多行多列的数据,当作一张临时表出现。
HAVING:子查询返回的一般是单行单列数据。
子查询在 WHERE 中出现
1.返回 单行单列 数据
范例一: 查询出工资比SMITH还要高的全部雇员信息
SELECT * FROM EMP WHERE sal>(SELECT sal FROM EMP WHERE ename='SMITH');
2.子查询返回 单行多列 数据
以上所返回的是单行单列,但是在子查询之中,也可以返回单行多列的数据,只是这种子查询很少出现。
范例:查询出emp表中 职位和薪资 与雇员 'SCOTT'的 职位和薪资 相同的雇员信息。
SELECT * FROM EMP WHERE (JOB,SAL)=(SELECT job,sal from emp where ename='SCOTT');
3.子查询返回 多行单列 数据
如果现在的子查询返回的是多行单列数据的话,这个时候就需要使用三种判断符判断了:IN、ANY、ALL;
IN 操作符
IN里面的范围由子查询指定。
案例:查询雇员的工资等于在经理的工资的范围内的雇员信息
SELECT * FROM EMP WHERE SAL IN (SELECT SAL FROM EMP WHERE JOB='MANAGER');
但是在使用IN的时候还要注意 NOT IN的问题,如果使用NOT IN操作,在子查询之中,如果有一个内容是null,则不会查询出任何的结果。
解决非空 问题,使用空判断NVL。
SELECT * FROM EMP WHERE SAL IN (SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
ANY操作符:与每一个内容想匹配,有三种匹配形式
=ANY:功能与IN操作符是完全一样的;
案例:查询雇员的工资等于在经理的工资的范围内的雇员信息
SELECT * FROM EMP WHERE SAL =ANY(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
>ANY:比子查询中返回记录最小的还要大的数据;
案例:查询雇员的工资比经理的工资高的雇员信息
SELECT * FROM EMP WHERE SAL >ANY(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
案例:查询雇员的工资比经理的工资低的雇员信息
SELECT * FROM EMP WHERE SAL
ALL操作符:与每一个内容相匹配,有两种匹配形式:
需要注意的是:ALL 。(如果有一个内容是null,则不会查询出任何的结果。)
>ALL:比子查询中返回的最大的记录还要大
案例:查询雇员的工资比经理的任意一个工资高的雇员信息
SELECT * FROM EMP WHERE SAL >ALL(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
案例:查询雇员的工资比经理的任意一个工资低的雇员信息
SELECT * FROM EMP WHERE SAL
子查询在 FROM 中出现
这个子查询一般返回的是多行多列的数据,当作一张临时表的方式来处理。
范例:查询出每个部门的编号、名称、位置、部门人数、平均工资
SELECT
d.DEPTNO 编号,
d.DNAME 名称,
d.LOC 位置,
temp.c 部门人数,
temp.a 平均工资
FROM DEPT d, (SELECT
DEPTNO dno,
count(SAL) c,
avg(SAL) a
FROM EMP
GROUP BY DEPTNO) temp
WHERE d.DEPTNO = temp.dno;
子查询在 HAVING 中出现(一般在条件判断出现统计函数的时候才使用)
范例:查询出职位的名称、人数、平均薪资,且要求 职位平均薪资高于公司平均薪资的,查询结果根据平均薪资降序排列。
SELECT
JOB 名称,
count(ENAME) 人数,
avg(SAL) 平均薪资
FROM EMP
GROUP BY JOB
HAVING avg(SAL) > (SELECT avg(sal)
FROM EMP)
ORDER BY 平均薪资 DESC;