子查询:
在一个查询的内部还包含另外一个查询
可在任意地方加入子查询代码,放在"()"中
eg:查询出比7654工资要高的全部雇员的信息。
首先清楚7654雇员的工资是多少
SELECT sal FROM emp WHERE empno=7654 ;
之后要以以上结果作为查询依据,只要是其他的工资大于sal,则表示
符合条件。
SELECT * FROM emp;
FROM sal>(SELECT sal FROM emp WHERE emp=7654) ;
子查询在操作中有分为以下三类:
单列子查询:返回的结果是一列的一个内容,出现几率高
单行子查询:返回多个列,有可能是一条完整的记录
多行子查询:返回多条记录
eg:查询出工资比7654高,同时与7788从事相同工作的全部雇员信息。
查询出7654的工资:
SELECT sal FROM emp WHERE emp=7654;
选出7788雇员的工作
SELECT job FROM emp WHERE empno=7788;
之后把两个条件进行综合查找
SELECT * FROM emp
WHERE sal>(SELECT sal FROM emp WHERE empno=7654)
AND job=(SELECT job FROM emp WHERE empno=7788) ;
eg:要求查处工资最低的雇员的姓名、工作、工资
SELECT MIN(sal) FROM emp;
SELECT * FROM emp
WHERE sal=(SELECT MIN(sal) FROM emp) ;
思考:
要求查询出部门的部门名称、部门的员工数、部门的平均工资,
部门的最低收入雇员的姓名和最高收入、雇员的姓名。
程序需要两张表关联:dept、emp
1、要求出每个部门的员工数,平均工资,则肯定要使用分组统计,按照deptno
进行分组,
SELECT deptno,COUNT(empno),AVG(sal)
FROM emp
GROUP BY deptno;
2、但是如果要想查出来部门的名称则需要与dept表进行关联。
SELECT d.dname,ed.c,ed.a
FROM dept d,
(SELECT deptno,COUNT(empno) c,AVG(sal) a
FROM emp GROUP BY deptno) ed;
WHERE d.deptno=ed.deptno ;
3、求出最低收入的雇员的姓名
SELECT d.dname,ed.c,ed.a,e.ename
FROM dept d,(
SELECT deptno,COUNT(emp) c,AVG(sal) a,
MIN(sal) min,MAX(sal) max
FROM emp
GROUP BY deptno) ed,emp e
WHERE d.deptno = ed.deptno AND e.sal=ed.min;
如果,在一个部门中同时存在两个工资最低的雇员,则程序就会出现错误。
在子查询中,存在三种查询操作符号:
IN 指定一个查询范围
ANY
ALL
IN 指定一个查询范围
eg:求出每个部门的最低工资的雇员信息
每个部门的最低工资返回的值肯定是多个,所以此时可以使用IN指定一个操作的范围。
WHERE * FROM emp
WHERE sal IN(select MIN(sal) FROM emp GROUP BY deptno) ;
ANY操作:
=ANY :与IN的操作符功能完全一样
SELECT * FROM emp
WHERE sal>ANY(SELECT MIN(sal) FROM emp GROUP BY deptno) ;
>ANY :比里面最小的值要大
SELECT * FROM emp
WHERE sal
>ALL :比最大的值要大的
>ALL :比最小的值要小的
SELECT * FROM emp
WHERE sal>ALL(SELECT MIN(sal) FROM emp GROUP BY deptno) ;
对于子查询来讲,还可以进行多列子查询,一个子查询中同时返回多个查询的列。
SELECT * FROM dept
WHERE (sal.NVL(comm,-1)) IN (
SELECT sa,NVL(comm,-1) FROM emp WHERE deptno=20)
;