[Oracle]高效的SQL語句之分析函式(三)
[Oracle]高效的SQL語句之分析函式(三)--row_number() /rank()/dense_rank()
有些時候我們希望得到指定資料中的前n列,示例如下:
得到每個部門薪水最高的三個僱員:
先建立示例表
create table emp
as
select * from scott.emp;
alter table emp
add constraint emp_pk
primary key(empno);
create table dept
as
select * from scott.dept;
alter table dept
add constraint dept_pk
primary key(deptno);
as
select * from scott.emp;
alter table emp
add constraint emp_pk
primary key(empno);
create table dept
as
select * from scott.dept;
alter table dept
add constraint dept_pk
primary key(deptno);
先看一下row_number() /rank()/dense_rank()三個函式之間的區別
select emp.deptno,emp.sal,emp.empno,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
結果如下:
10 5000.00 7839 1 1 1
10 2450.00 7782 2 2 2
10 1300.00 7934 3 3 3
20 3000.00 7788 1 1 1
20 3000.00 7902 2 1 1
20 2975.00 7566 3 3 2
20 1100.00 7876 4 4 3
20 800.00 7369 5 5 4
30 2850.00 7698 1 1 1
30 1600.00 7499 2 2 2
10 2450.00 7782 2 2 2
10 1300.00 7934 3 3 3
20 3000.00 7788 1 1 1
20 3000.00 7902 2 1 1
20 2975.00 7566 3 3 2
20 1100.00 7876 4 4 3
20 800.00 7369 5 5 4
30 2850.00 7698 1 1 1
30 1600.00 7499 2 2 2
取每個部門的薪水前三位僱員:
select t.deptno,t.rank,t.sal from
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
結果如下:
10 1 5000.00
10 2 2450.00
10 3 1300.00
20 1 3000.00
20 1 3000.00
20 3 2975.00
30 1 2850.00
30 2 1600.00
30 3 1500.00
10 2 2450.00
10 3 1300.00
20 1 3000.00
20 1 3000.00
20 3 2975.00
30 1 2850.00
30 2 1600.00
30 3 1500.00
如果想輸出成deptno sal1 sal2 sal3這種型別的格式
步驟一(decode):
select t.deptno,decode(row_number,1,sal) sal1,decode(row_number,2,sal) sal2,decode(row_number,3,sal) sal3 from
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
結果如下:
10 5000
10 2450
10 1300
20 3000
20 3000
20 2975
30 2850
30 1600
30 1500
10 2450
10 1300
20 3000
20 3000
20 2975
30 2850
30 1600
30 1500
步驟二(使用聚合函式去除null,得到最終結果):
select t.deptno,max(decode(row_number,1,sal)) sal1,max(decode(row_number,2,sal)) sal2,max(decode(row_number,3,sal)) sal3 from
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
group by t.deptno
(
select emp.*,row_number() over (partition by deptno order by sal desc) row_number, --1,2,3
rank() over (partition by deptno order by sal desc) rank, --1,1,3
dense_rank() over (partition by deptno order by sal desc) dense_rank from emp --1,1,2
) t
where t.rank<=3
group by t.deptno
結果如下:
10 5000 2450 1300
20 3000 3000 2975
30 2850 1600 1500
20 3000 3000 2975
30 2850 1600 1500
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/219982/viewspace-513636/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [Oracle]高效的SQL語句之分析函式(一)(二)OracleSQL函式
- [Oracle]高效的SQL語句之分析函式(四)--lag()/lead()OracleSQL函式
- 高效率Oracle SQL語句OracleSQL
- SQL Server SQL語句中的函式呼叫與Oracle SQL語句函式呼叫一個有趣的差別SQLServer函式Oracle
- sql語句之分組,聚合函式SQL函式
- 【SQL】Oracle sql語句 minus函式執行效率與join對比SQLOracle函式
- Oracle之sql語句優化OracleSQL優化
- oracle之PLSql語言(二)sql語句的使用OracleSQL
- oracle的sql語句OracleSQL
- Oracle PL/SQL 之 函式OracleSQL函式
- Oracle SQL語句優化之UNIONOracleSQL優化
- 兩個SQL語句技巧——NULLS FIRST/LAST和分析函式版AVGSQLNullAST函式
- 《卸甲筆記》-PostgreSQL和Oracle的SQL差異分析之五:函式的差異(三)筆記SQLOracle函式
- ORACLE SQL語句優化技術分析OracleSQL優化
- oracle sql語句OracleSQL
- 高效SQL語句必殺技SQL
- Oracle經典sql語句總結@sql-plus重點函式串講與sql語句案例@中文排序詳講).docOracleSQL函式排序
- ORACLE優化SQL語句,提高效率(1)Oracle優化SQL
- ORACLE優化SQL語句,提高效率(2)Oracle優化SQL
- ORACLE優化SQL語句,提高效率(3)Oracle優化SQL
- 【分析函式】Oracle分析函式之LAG和LEAD函式Oracle
- MyBatis學習 之 三、動態SQL語句MyBatisSQL
- Oracle SQL語句最佳化技術分析OracleSQL
- ORACLE SQL語句優化技術分析(zt)OracleSQL優化
- ORACLE SQL語句優化技術分析(轉)OracleSQL優化
- sql語句的優化分析SQL優化
- 透過sql語句分析足彩(第三篇)SQL
- 通過sql語句分析足彩(第三篇)SQL
- Oracle Decode()函式和CASE語句的比較Oracle函式
- Oracle基本SQL語句OracleSQL
- oracle常用SQL語句OracleSQL
- oracle的表分析語句Oracle
- 編寫高效 SQL 語句的最佳實踐SQL
- ORACLE很重要的sql語句OracleSQL
- 通過分析SQL語句的執行計劃優化SQL語句SQL優化
- sql語句的優化案例分析SQL優化
- SQL視窗分析函式使用詳解系列三之偏移量類視窗函式SQL函式
- 如何寫出高效能SQL語句SQL