子查询
- 子查询语法中的小括号
语法中一定要有小括号,不然是错的。
- 子查询的书写风格
该换行的换行,该缩进的索引,可以便于阅读。
- 可以使用子查询的位置:where,select,having,from
select后面使用,要求一定要只返回一条记录,要是单行子查询才行,多行子查询不行。
如
SELECT empno,ename,sal,(SELECT job FROM emp WHERE empno=7839) 第四列
FROM emp;
在having后面使用:
如
SELECT deptno,AVG(sal)
FROM emp
GROUP BY deptno
HAVING AVG(sal) > (SELECT MAX(sal)
FROM emp
WHERE deptno=30);
在from后面放置:
非常的重要,很多问题都是在from后面方式子查询来解决的
如
SELECT * from(SELECT empno,ename,sal FROM emp);
- 不可以使用子查询的位置:group by
如
SELECT AVG(sal)
FROM emp
GROUP BY (SELECT deptno FROM emp); --会报错,这里不允许出现子查询表达式
- 强调:from后面的子查询,比较特殊,比较重要
如
SELECT *
FROM (SELECT empno,ename,sal,sal*12 annsal FROM emp);
- 主查询和子查询可以不是同一张表
如
SELECT * FROM emp WHERE deptno=
(SELECT deptno
FROM dept
WHERE dname='SALES');
多表查询代码:
SELECT e.*
FROM emp e,dept d
WHERE e.deptno=d.deptno AND d.dname='SALES';
哪种查询方式好呢?从理论上来讲,尽量使用多表查询比较好,因为子查询需要对数据库访问两次,而多表查询只需要对数据库访问一次。但实际情况下有可能不一样,因为多表查询的笛卡尔集可能很大所以慢了。
- 一般不在子查询中,使用排序;但在Top-N分析问题中,必须对子查询排序
比如找到员工表中工资最高的前三名。
rownum
行号,是一个伪列,表上没有这一列,当做一些特殊操作的时候,oracle自动加上。行号需要注意的问题:行号永远按照默认的顺序生成;行号只能使用<,<=,不能使用>或者>=这样的符号。
如
SELECT ROWNUM,empno,ename,sal
FROM (SELECT * FROM emp ORDER BY sal DESC)
WHERE ROWNUM<=3;
- 一般先执行子查询,再执行主查询;但相关子查询例外
相关子查询的表必须设定一个别名,然后把主查询的内容传入到子查询中进行查询。
如
SELECT empno,ename,sal,(SELECT AVG(sal) FROM emp WHERE deptno=e.deptno) avgsal
FROM emp e
WHERE sal > (SELECT AVG(sal) FROM emp WHERE deptno=e.deptno);
这里就把主查询e表中的部门号传入子查询中进行查询了。
- 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符