Oracle高级查询之over(partitionby..)(一)

2015-03-04 17:07:54 · 作者: · 浏览: 140

为了方便学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。

create table EMP
(
? empno ? ?NUMBER(4) not null,
? ename ? ?VARCHAR2(10),
? job ? ? ?VARCHAR2(9),
? mgr ? ? ?NUMBER(4),
? hiredate DATE,
? sal ? ? ?NUMBER(7,2),
? comm ? ? NUMBER(7,2),
? deptno ? NUMBER(2)
)
alter table EMP
? add constraint PK_EMP primary key (EMPNO);

insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800, null, 20);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-02-1981', 'dd-mm-yyyy'), 1600, 300, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7521, 'WARD', 'SALESMAN', 7698, to_date('22-02-1981', 'dd-mm-yyyy'), 1250, 500, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7566, 'JONES', 'MANAGER', 7839, to_date('02-04-1981', 'dd-mm-yyyy'), 2975, null, 20);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-09-1981', 'dd-mm-yyyy'), 1250, 1400, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7698, 'BLAKE', 'MANAGER', 7839, to_date('01-05-1981', 'dd-mm-yyyy'), 2850, null, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7782, 'CLARK', 'MANAGER', 7839, to_date('09-06-1981', 'dd-mm-yyyy'), 2450, null, 10);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7788, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987', 'dd-mm-yyyy'), 3000, null, 20);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7839, 'KING', 'PRESIDENT', null, to_date('17-11-1981', 'dd-mm-yyyy'), 5000, null, 10);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7844, 'TURNER', 'SALESMAN', 7698, to_date('08-09-1981', 'dd-mm-yyyy'), 1500, 0, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7876, 'ADAMS', 'CLERK', 7788, to_date('23-05-1987', 'dd-mm-yyyy'), 1100, null, 20);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7900, 'JAMES', 'CLERK', 7698, to_date('03-12-1981', 'dd-mm-yyyy'), 950, null, 30);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7902, 'FORD', 'ANALYST', 7566, to_date('03-12-1981', 'dd-mm-yyyy'), 3000, null, 20);
insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno)?
? ? ? ?values (7934, 'MILLER', 'CLERK', 7782, to_date('23-01-1982', 'dd-mm-yyyy'), 1300, null, 10);

?

注:标题中的红色order by是说明在使用该方法的时候必须要带上order by

一、rank()/dense_rank() over(partition by ...order by ...)

现在客户有这样一个需求,查询每个部门工资最高的雇员的信息,相信有一定oracle应用知识的同学都能写出下面的SQL语句:

?

select * from (select ename, job, hiredate, e.sal, e.deptno
          from emp e,
               (select deptno, max(sal) sal from emp group by deptno) t
         where e.deptno = t.deptno
           and e.sal = t.sal)
 order by deptno;
        
select * from (select ename 姓名, job 职业, hiredate 入职日期, e.sal 工资, e.deptno 部门
          from emp e,
               (select deptno, max(sal) sal from emp group by deptno) t
         where e.deptno = t.deptno
           and e.sal = t.sal)
 order by 部门;

?

\
在满足客户需求的同时,大家应该习惯性的思考一下是否还有别的方法。这个是肯定的,就是使用本小节标题中rank() over(partition by...)或dense_r