oracle中的RANK()和DENSE_RANK()函数有什么区别?
RANK()
和DENSE_RANK()
函数有什么区别? 如何find以下emptbl
表中的第n个工资?
DEPTNO EMPNAME SAL ------------------------------ 10 rrr 10000.00 11 nnn 20000.00 11 mmm 5000.00 12 kkk 30000.00 10 fff 40000.00 10 ddd 40000.00 10 bbb 50000.00 10 ccc 50000.00
如果表中的数据为nulls
,如果我想找出nth
工资,会发生什么?
RANK给你在你的有序分区内的排名。 领带被赋予相同的等级,下一个等级被跳过。 所以,如果你有3个项目在排名第二,列出的下一个排名将排名5。
DENSE_RANK再次为您提供sorting在您的有序分区,但排名是连续的。 如果有多个项目的等级,则不会跳过等级。
至于空值,则取决于ORDER BY子句。 下面是一个简单的testing脚本,你可以用它来看看会发生什么:
with q as ( select 10 deptno, 'rrr' empname, 10000.00 sal from dual union all select 11, 'nnn', 20000.00 from dual union all select 11, 'mmm', 5000.00 from dual union all select 12, 'kkk', 30000 from dual union all select 10, 'fff', 40000 from dual union all select 10, 'ddd', 40000 from dual union all select 10, 'bbb', 50000 from dual union all select 10, 'xxx', null from dual union all select 10, 'ccc', 50000 from dual) select empname, deptno, sal , rank() over (partition by deptno order by sal nulls first) r , dense_rank() over (partition by deptno order by sal nulls first) dr1 , dense_rank() over (partition by deptno order by sal nulls last) dr2 from q; EMP DEPTNO SAL R DR1 DR2 --- ---------- ---------- ---------- ---------- ---------- xxx 10 1 1 4 rrr 10 10000 2 2 1 fff 10 40000 3 3 2 ddd 10 40000 3 3 2 ccc 10 50000 5 4 3 bbb 10 50000 5 4 3 mmm 11 5000 1 1 1 nnn 11 20000 2 2 2 kkk 12 30000 1 1 1 9 rows selected.
这里有一个很好的解释和一些例子的链接 。
这篇文章很好地解释了它。 基本上,你可以这样看待它:
CREATE TABLE t AS SELECT 'a' v FROM dual UNION ALL SELECT 'a' FROM dual UNION ALL SELECT 'a' FROM dual UNION ALL SELECT 'b' FROM dual UNION ALL SELECT 'c' FROM dual UNION ALL SELECT 'c' FROM dual UNION ALL SELECT 'd' FROM dual UNION ALL SELECT 'e' FROM dual; SELECT v, ROW_NUMBER() OVER (ORDER BY v) row_number, RANK() OVER (ORDER BY v) rank, DENSE_RANK() OVER (ORDER BY v) dense_rank FROM t ORDER BY v;
以上将产生:
+---+------------+------+------------+ | V | ROW_NUMBER | RANK | DENSE_RANK | +---+------------+------+------------+ | a | 1 | 1 | 1 | | a | 2 | 1 | 1 | | a | 3 | 1 | 1 | | b | 4 | 4 | 2 | | c | 5 | 5 | 3 | | c | 6 | 5 | 3 | | d | 7 | 7 | 4 | | e | 8 | 8 | 5 | +---+------------+------+------------+
换句话说
-
ROW_NUMBER()
为每一行赋予一个唯一的值 -
RANK()
将相同的行号赋予相同的值,留下“孔” -
DENSE_RANK()
将相同的行号赋予相同的值,不留下“孔”
SELECT empno, deptno, sal, RANK() OVER (PARTITION BY deptno ORDER BY sal) "rank" FROM emp; EMPNO DEPTNO SAL rank ---------- ---------- ---------- ---------- 7934 10 1300 1 7782 10 2450 2 7839 10 5000 3 7369 20 800 1 7876 20 1100 2 7566 20 2975 3 7788 20 3000 4 7902 20 3000 4 7900 30 950 1 7654 30 1250 2 7521 30 1250 2 7844 30 1500 4 7499 30 1600 5 7698 30 2850 6 SELECT empno, deptno, sal, DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal) "rank" FROM emp; EMPNO DEPTNO SAL rank ---------- ---------- ---------- ---------- 7934 10 1300 1 7782 10 2450 2 7839 10 5000 3 7369 20 800 1 7876 20 1100 2 7566 20 2975 3 7788 20 3000 4 7902 20 3000 4 7900 30 950 1 7654 30 1250 2 7521 30 1250 2 7844 30 1500 3 7499 30 1600 4 7698 30 2850 5
RANK()和DENSE_RANK()函数之间的唯一区别是在有“tie”的情况下。 即在一组中的多个值具有相同的排名的情况下。 在这种情况下,RANK()会给集合中的值分配非连续的“等级”(当存在并列时,导致整数排列值之间的差距),而DENSE_RANK()将连续的等级分配给设置(所以在并列情况下,整数排名值之间不会有差距)。
例如,考虑一组{25,25,50,75,75,100}。 对于这样的集合,RANK()将返回{1,1,3,4,4,6}(注意值2和5被跳过),而DENSE_RANK()将返回{1,1,2,3, 3,4}。
rank() :它用于对一组行中的logging进行sorting。
dense_rank() :DENSE_RANK函数的作用与RANK函数类似,只是它分配了连续的排列。
查询 –
select ENAME,SAL,RANK() over (order by SAL) RANK from EMP;
输出 –
+--------+------+------+ | ENAME | SAL | RANK | +--------+------+------+ | SMITH | 800 | 1 | | JAMES | 950 | 2 | | ADAMS | 1100 | 3 | | MARTIN | 1250 | 4 | | WARD | 1250 | 4 | | TURNER | 1500 | 6 | +--------+------+------+
查询 –
select ENAME,SAL,dense_rank() over (order by SAL) DEN_RANK from EMP;
输出 –
+--------+------+-----------+ | ENAME | SAL | DEN_RANK | +--------+------+-----------+ | SMITH | 800 | 1 | | JAMES | 950 | 2 | | ADAMS | 1100 | 3 | | MARTIN | 1250 | 4 | | WARD | 1250 | 4 | | TURNER | 1500 | 5 | +--------+------+-----------+
select empno ,salary ,row_number() over(order by salary desc) as Serial ,Rank() over(order by salary desc) as rank ,dense_rank() over(order by salary desc) as denseRank from emp ;
Row_number()
– >用于生成序列号
Dense_rank()
将给予连续的等级,但是在等级冲突的情况下等级将跳过等级。