01
—
复杂查询
复杂查询大部分包括子查询,可能需要执行初始化脚本恢复工整的数据。
子查询
子查询也称嵌套查询,是一种嵌套在其他SQL语句的WHERE子句中的查询。子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。语法如下:
代码语言:javascript复制select 字段1,字段2,... from 表名 where 字段名 操作符 (子查询);
代码语言:javascript复制
查询入职时间比Joe晚的员工的姓名,把复杂的问题简单化的方法是分步执行。
代码语言:javascript复制-- 子查询
-- 查询入职时间比Joe晚的员工的姓名
select hiredate from emp where ename='Joe';
select ename from emp where hiredate > '2013-01-03';
-- merge to one SQL
select ename from emp
where hiredate>(select hiredate from
emp where ename='Joe');
select e1.ename from emp e1 join emp e2 on e1.hiredate>e2.hiredate
where e2.ename='Joe';
代码语言:javascript复制
练习
查询工资高于平均工资的员工
代码语言:javascript复制select ename,sal
from emp
where sal>(
select avg(sal)
from emp
);
代码语言:javascript复制
子查询和连接
子查询和连接之间的经常可以进行互换改写,例如前面的SQL可以改成:
代码语言:javascript复制select e1.ename from emp e1 join emp e2 on e1.hiredate>e2.hiredate
where e2.ename='Joe';
代码语言:javascript复制
SELECT子句中的子查询
在select子句中可以包括子查询
代码语言:javascript复制select ename,sal,(select avg(sal) from emp) average_salary from emp;
代码语言:javascript复制
员工和对应部门的平均工资,要使用到相关子查询
代码语言:javascript复制select ename,sal,(select avg(sal) from emp where deptno=e.deptno) average_salary from emp e;
代码语言:javascript复制
FROM子句中的子查询
上一节中我们查询员工和对应部门的平均工资。
我们也可以把这个SQL的返回结果作为一个表放到form子句中,并加上条件
代码语言:javascript复制select *
from
(
select ename,sal,(select avg(sal) from emp where deptno=e.deptno) average_salary from emp e
) e2 where average_salary>10000 ;
代码语言:javascript复制
ALL关键字
ALL关键字从字面上面理解就是指集合中的所有值。
查询比2号部门所有员工工资高的员工
代码语言:javascript复制-- the ALL keyword
select ename from emp where sal > (select max(sal) from emp where deptno=2);
代码语言:javascript复制
all表示集合中的所有值,使用all进行改写
代码语言:javascript复制select ename from emp where sal > all (select sal from emp where deptno=2);
代码语言:javascript复制
ANY关键字
ANY关键字从字面上面理解就是指集合中的任一值。
查询比2号部门任一员工工资高的员工
代码语言:javascript复制-- the any keyword
select ename from emp where sal > (select min(sal) from emp where deptno=2);
代码语言:javascript复制
any表示集合中的任意一个
代码语言:javascript复制select ename from emp where sal > any (select sal from emp where deptno=2);
代码语言:javascript复制
ANY关键字的练习
下面的SQL是用in判断员工号为1、2、3中任一值,既然any表示集合中的任一值,请用any改写这个SQL,去掉in。(答案见讲义)
代码语言:javascript复制
代码语言:javascript复制SQL> select ename from emp where empno in (1,2,3);
ENAME
----------
Grace
Joe
John
答案
SQL> select ename from emp where empno =any (1,2,3);
ENAME
----------
Grace
Joe
John
相关子查询
相关子查询是在子查询使用外部查询中的值
查询出比自己部门平均工资高的员工
代码语言:javascript复制update emp set sal=20000 where empno=5;
select ename,deptno,sal from emp e where sal > ( select avg(sal) from emp);
select avg(sal) from emp;
select ename,deptno,sal from emp e where sal > ( select avg(sal) from emp where deptno=e.deptno);
这里的外部查询是指
select ename,deptno,sal from emp e where sal >
相关子查询是
select avg(sal) from emp where deptno=e.deptno
EXISTS运算符
EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,没有返回 False。
exists运算符和in运算符之间通常可以相互改写。
查询部门号存在在部门表中的员工
代码语言:javascript复制insert into emp values(7,'Kim',4,null,10000,null);
select * from emp where exists(select 1 from dept where emp.deptno =dept.deptno ) ;
select * from emp where not exists(select 1 from dept where emp.deptno =dept.deptno ) ;
用in改写
代码语言:javascript复制select * from emp where emp.deptno in (select dept.deptno from dept) ;
select * from emp where emp.deptno not in (select dept.deptno from dept) ;
未完,请查看SQL语言基础知识(六)