不等值连接查询

  • 员工工资级别
  • select e.empno,e.ename,e.sal,s.grade
  • from emp e,salgrade s
  • where e.sal between s.losal and s.hisal

外连接

  • 外连接的意义:对于某些不成立的记录,仍然希望包含在最后的结果集中。

  • 左外连接:当where e.deptno = d.deptno 不成立时,等号左边表的任意项仍被包含

  • 左外连接写法: where e.deptno = d.deptno(+)

  • 右外连接写法: where e.deptno = d.deptno(+)

  • 按部门统计员工人数:部门号,部门名称,人数, (右外连接)

  • select d.deptno, d.dname,count(e.empno)

  • from emp e,dept d

  • where e.deptno(+) = d.deptno

  • group by d.deptno, d.dname

  • order by d.deptno

层次查询

  • 只有一张表,单表查询,自连接为多表查询
  • select level, empno, ename, mgr
  • from emp
  • connect by prior empno = mgr
  • start with mgr is null
  • order by 1
  • level 为伪列,显示层次中的级别

子查询

  • 可以在主查询的where, select, having, from 后放置子查询
  • 不可以在group by后放置子查询
  • 主查询和子查询可以不是同一张表,只要子查询返回的结果主查询可用即可
  • 一般不在子查询中使用排序,但在Top-N的子查询中要排序
  • 子查询一般在主查询执行前执行完成,但相关子查询例外
  • 单行子查询(即只返回一条记录的查询)只能使用单行操作符,多行子查询只能使用多行操作符

多行子查询

  • 返回多行,使用多行比较操作符
  • in: 等于列表中的任何一个
  • any:和子查询返回的任意一个值比较(min())
  • all:和子查询返回的所有制比较(max())
  • 查询工资比30号部门任意一个员工高的员工
  • select * from emp where sal > any(select sal from emp where deptno = 30);
  • 不是老板的员工,所有的叶子节点
  • select * from emp where empno not in (select mgr from emp where mgr is not null);
  • 找到员工中工资最高的前3名
  • select rownum, empno, ename, sal
  • from (select * from emp order by sal desc)
  • where rownum <= 3;
  • 找到员工表中薪水大于本部门平均薪水的员工
  • select e.empno,e.ename,e.sal,d.avgsal
  • from emp e, (select deptno, avg(sal) avgsal from emp group by deptno) d
  • where e.deptno = d.deptno and e.sal > d.avgsal

相关子查询

  • 将主查询中的某些值作为参数传递给子查询
  • 找到员工表中薪水大于本部门平均薪水的员工
  • select e.empno, e.ename,e.sal, (select avg(sal) from emp where deptno = e.deptno) avgsal
  • from emp e
  • where e.sal > (select avg(sal) from emp where deptno = e.deptno)
  • 统计每年入职人数
    select count(*) Total,
    sum(decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
    sum(decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
    sum(decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
    sum(decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987"
    from emp;

分页

select * 
from (select rownum r, e1.* 
	from (select * from emp order by sal) e1
	where rownum <=8 )
where r >= 5;