分组函数会忽视空值,nvl函数使分组函数无法忽略空值。
笛卡尔集:列数=各个表列数之和,行数=行数相乘
等值连接:用=
不等值连接:没有使用=
查询 每个部门的员工数。
select dept.no,dept.name,count(emp.no)
from dept,emp
where
group by dept.no,dept.name
后果是忽视在emp表中,某个部门没有人数,但现实时应显示 该部门员工数为 0。
外连接:通过外连接,把对于连接条件不成立的记录,仍然包含在最后的结果中。
select dept.no,dept.name,count(emp.no)
from dept,emp
where dept.deptno=emp.deptno(+)(左外连接)
//where emp.deptno(+)=dept.deptno(右外连接)
group by dept.no,dept.name
自连接:通过别名,将一张表视为多张表
from emp e,emp b where e.mgr=b.empno
不适合操作大表,解决方法:层次查询
从根节点一层一层遍历
selec level,empno,ename,sal
from emp
connect by prior empnp=mgr
start with mgr is null
order by 1
select deptno,wm_conccat(ename) from emp group by deptno.
1、可以使用子查询的位置:select、from、where、having
不能使用子查询的位置:group by
select 后面跟着的必须是单行子查询,即一个字段
where语句里面不可以使用组函数,having可以
2、 一般先执行子查询,在执行主查询;但是相关子查询除外。
3、 单行子查询只能使用单行操作符,多行子查询只能使用多行查询符
单行操作符:=、> ,>=,<,<=
多行操作符:in,any,all
4、一般不在子查询中使用用排序,但在Top-N问题中一定要使用排序
行号永远按照默认的顺序生成,涉及到临时表。
行号只能使用<,<=;不能使用>,>=
select rownum,enpno
from (select * from emp order by sal desc)
where rownum<3;
相关子查询中的主表 需要起一个别名
select enmno,(select avg(sal) from emp where deptno=e.deptno) agasal
from emp e
where sal>(select avg(sal) from emp where deptno=e.detpno);
理论上 多表查询好于子查询,多表查询会产生多个笛卡尔集,实际上可能子查询好于多表查询。
5、子查询中的空值问题
多行子查询的空值问题:
a not in (10,20,null)
equal a!=10 and a!=20 and a!=null,其中a!=null 始终为false,
要保证多行子查询返回的结果中不包含空值或对空值进行处理(isnull)
oracle是行式数据库,取了第一行才能取第二行,永远从1开始
oracle中的分页是通过嵌套子查询的方式处理的。
select rownum,r,empno,sal
from ( select r,empno,sal
from ( select rownum,empno,sal from emp order by sal desc) e1
where rornum<8) e2
where r>5
将伪列变成不是伪列,进而可以进行大于等于,between操作。
explain plan for
--执行的SQL语句
select * from table(dbms_xplain.display)