先准备数据: deptid :部门id. parent_deptid :deptid 的父级部门,也就是depid 是他的子部门。 create table test_employee (empid int,deptid int,parent_deptid int,salary decimal(10,2)); insert into test_employee values(1,10,100,5500.00); insert into test_employee values(2,200,4500.00); insert into test_employee values(3,20,1900.00); insert into test_employee values(4,4800.00); insert into test_employee values (5,40,6500.00); insert into test_employee values (6,14500.00); insert into test_employee values (7,44500.00); insert into test_employee values (8,50,6500.00); insert into test_employee values (9,7500.00); 假设说存在这么一个需求,需要获得所有子部门里薪水最高的那部分员工, 需要
显示的字段有 empid,deptid,parent_deptid,salary 先简单介绍下这个
sql中会遇到的一些关键的点: 1.row_number select rownum,te.* from test_employee te ; 以上
sql语句将获得以下结果: ROWNUM EMPID DEPTID PARENT_DEPTID SALARY 1 **1 10 100 5500** 2 2 10 200 4500 3 3 20 100 1900 4 4 20 200 4800 5 5 40 100 6500 6 6 40 200 14500 7 7 40 200 44500 8 8 50 100 6500 9 9 50 200 7500 注意粗体部分,现在rownum 是1, 按如下
sql来查: select rownum,te.* from test_employee te order by te.empid desc; 结果变成: ROWNUM EMPID DEPTID PARENT_DEPTID SALARY 1 2 10 200 4500 2 3 20 100 1900 3 4 20 200 4800 4 5 40 100 6500 5 6 40 200 14500 6 7 40 200 44500 7 8 50 100 6500 8 9 50 200 7500 empid为1 的记录不见了,但rownum 仍旧从1开始,也就说 rownum实际上就是
查询自结果的一个逻辑排序。 2.利用分析
函数(oracle)**row_number()以及**over()来分组筛选出符合条件的记录,注意在当rownumber与over()配合使 用时,是写法不一样的,注意粗体部分。 执行以下
sql: select row_number()over(partition by te.deptid order by te.salary desc) rn,te.* from test_employee te order by empid ; 将会得到如下结果: RN EMPID DEPTID PARENT_DEPTID SALARY 1 1 10 100 5500 2 2 10 200 4500 2 3 20 100 1900 1 4 20 200 4800 3 5 40 100 6500 2 6 40 200 14500 1 7 40 200 44500 2 8 50 100 6500 1 9 50 200 7500 可以看出通过row_number()over(partition by te.deptid order by te.salary desc) rn这个分析
函数已经通过deptid来分组 并通过薪水 来降序排列,那么在这个分组里薪水高的row_number将会是1,之后的 依次往后累加1,然后在通过
查询以上上这个结果集,并
加上条件rn=1 就能查出薪水最高的那位了,
sql如下: select * from (select row_number()over(partition by te.deptid order by te.salary desc) rn,te.* from test_employee te)t1 where rn=1; RN EMPID DEPTID PARENT_DEPTID SALARY 1 1 10 100 5500 1 4 20 200 4800 1 7 40 200 44500 1 9 50 200 7500 如果想要得到薪水少的,只需要将分析
函数中的order by desc 改成asc即可,那么薪水最低的RN 将会是1 select row_number()over(partition by te.deptid order by te.salary asc) rn,te.* from test_employee te order by empid ; RN EMPID DEPTID PARENT_DEPTID SALARY 2 1 10 100 5500 **1 2 10 200 4500** **1 3 20 100 1900** 2 4 20 200 4800 **1 5 40 100 6500** 2 6 40 200 14500 3 7 40 200 44500 **1 8 50 100 6500** 2 9 50 200 7500 select * from (select row_number()over(partition by te.deptid order by te.salary asc) rn,te.* from test_employee te)t1 where rn=1; RN EMPID DEPTID PARENT_DEPTID SALARY 1 2 10 200 4500 1 3 20 100 1900 1 5 40 100 6500 1 8 50 100 6500 同理如果要使用2个或以上字段来进行分组,上面的数据有点不对,一个 小部分只能属于一个大部门,稍微改下数据: drop table test_employee; create table test_employee (empid int,gender varchar(1),'F','M',7500.00); 如假设存在以下条件,找出部门里的男女员工各自的最高薪(用一个
sql语句查出): ROWNUM EMPID DEPTID GENDER SALARY 1 1 10 F 5500 2 2 10 M 4500 3 3 10 M 1900 4 4 10 F 4800 **5 5 20 M 6500** 6 6 20 M 14500 7 7 20 F 44500 **8 8 20 M 6500** 9 9 20 F 7500 select * from (select row_number()over(partition by te.deptid,gender order by te.salary desc) rn,te.* from test_employee te)t1 where rn=1; 结果如下: RN EMPID DEPTID GENDER SALARY 1 1 10 F 5500 1 2 10 M 4500 1 7 20 F 44500 1 6 20 M 14500 如果数据中同一分组存在两条相同的排序数据,如何处理(如都为6500,M,20部分的),先改成数据如下: ROWNUM EMPID DEPTID GENDER SALARY 1 1 10 F 5500 2 2 10 M 4500 3 3 10 M 1900 4 4 10 F 4800 5 5 20 M 6500 6 6 20 M 2500 7 7 20 F 44500 8 8 20 M 6500 9 9 20 F 7500 select * from (select row_number()over(partition by te.deptid,te.* from test_employee te)t1 where rn=1; 如下,empid=5 的被取出来了,原因是第一排序是salary,之后按empid默认升序排序: RN EMPID DEPTID GENDER SALARY 1 1 10 F 5500 1 2 10 M 4500 1 7 20 F 44500 **1 5 20 M 6500** 做个测试,再salary 后再加个empid 降序排列,那么是否应该empid=8的6500会被取出来?
查询结果如下: RN EMPID DEPTID GENDER SALARY 1 1 10 F 5500 1 2 10 M 4500 1 7 20 F 44500 **1 8 20 M 6500** 结果如我所想empid=8的将会被取出来。 总结: 以上不能用group by,因为select 只能是group by后的字段。 partition 是按部分字段分组的意思。
原文链接:https://www.f2er.com/oracle/212137.html