RANK()
和DENSE_RANK()
功能之间的区别是什么?如何在以下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
薪水会怎样?
答案 0 :(得分:203)
RANK为您提供订购分区内的排名。领带被分配相同的排名,跳过下一个排名。因此,如果您在排名2中有3个项目,则列出的下一个排名将排名为5.
DENSE_RANK再次为您提供有序分区内的排名,但排名是连续的。如果有多个项目的排名,则不会跳过任何排名。
对于null,它取决于ORDER BY子句。这是一个简单的测试脚本,您可以使用它来查看会发生什么:
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.
Here's a link给出了一个很好的解释和一些例子。
答案 1 :(得分:77)
This article here nicely explains it.基本上,你可以这样看:
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()
将相同的行号归为相同的值,留下“holes”DENSE_RANK()
将相同的行号归属为相同的值,不留任何“漏洞”答案 2 :(得分:9)
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
答案 3 :(得分:6)
rank():用于对一组行中的记录进行排名。
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 |
+--------+------+-----------+
答案 4 :(得分:2)
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()
会给出持续排名但排名会在排名冲突的情况下跳过排名。
答案 5 :(得分:2)
RANK()和DENSE_RANK()函数之间的唯一区别是存在“平局”;即,在集合中的多个值具有相同排名的情况下。在这种情况下,RANK()会为集合中的值分配非连续的“排名”(当存在平局时导致整数排名值之间的差距),而DENSE_RANK()将连续排名分配给set(因此在平局的情况下,整数排名值之间不会有间隙)。
例如,考虑集{25,25,50,75,75,100}。对于这样的集合,RANK()将返回{1,1,3,4,4,6}(注意跳过值2和5),而DENSE_RANK()将返回{1,1,2,3, 3,4}。
答案 6 :(得分:1)
Rank()SQL函数生成数据在有序值集中的排名,但上一个排名之后的下一个排名是该特定行的row_number。另一方面,Dense_Rank()SQL函数将生成下一个数字,而不是生成row_number。以下是将阐明概念的SQL示例:
Select ROW_NUMBER() over (order by Salary) as RowNum, Salary,
RANK() over (order by Salary) as Rnk,
DENSE_RANK() over (order by Salary) as DenseRnk from (
Select 1000 as Salary union all
Select 1000 as Salary union all
Select 1000 as Salary union all
Select 2000 as Salary union all
Select 3000 as Salary union all
Select 3000 as Salary union all
Select 8000 as Salary union all
Select 9000 as Salary) A
它将生成以下输出:
----------------------------
RowNum Salary Rnk DenseRnk
----------------------------
1 1000 1 1
2 1000 1 1
3 1000 1 1
4 2000 4 2
5 3000 5 3
6 3000 5 3
7 8000 7 4
8 9000 8 5
答案 7 :(得分:0)
Rank and Dense rank给出了分区数据集中的排名。
Rank():它不会为您提供连续的整数。
Dense_rank():它为您提供连续的整数。
在上面的图片中,考虑到row_number时,10008 zip的排名通过density_rank()函数为2,通过rank()函数为24。
答案 8 :(得分:0)
Rank(), Dense_rank(), row_number()
这些都是窗口函数,这意味着它们首先充当某个有序输入集上的窗口。这些窗口根据需要具有不同的功能。这是上面的3:
row_number()
从row_number()
开始,因为这形成了这些相关窗口功能的基础。顾名思义,row_number()
为应用行的行集提供了唯一的编号。类似于为每一行提供序列号。
Rank()
row_number()
的颠覆可以称为rank()
。 Rank()用于为重复的那些有序集行赋予相同的序列号,但对于在rank()之后重复的所有行,仍然保持与row_number()
类似的计数,这是从下面开始的。对于数据2 row_number()= rank(),这意味着两者的重复形式有所不同。
Data row_number() rank() dense_rank()
1 1 1 1
1 2 1 1
1 3 1 1
2 4 4 2
最后,
Dense_rank()是rank()的扩展版本,顾名思义,它是致密的,因为如上例所示,对于所有数据1,rank()= density_rank()只是对数据2而言,它的区别在于它保留了先前的rank()而不是实际数据的rank()顺序的形式
答案 9 :(得分:0)
RANK()和DENSE_RANK()函数之间的唯一区别是在存在“领带”的情况下;即,如果一组中的多个值具有相同的排名。在这种情况下,RANK()将不连续的“等级”分配给集合中的值(导致出现平局时导致整数排名值之间的间隔),而DENSE_RANK()将连续的等级分配给集合中的值设置(因此,在平局的情况下,整数排名值之间不会有间隙)。
例如,考虑一组{30,30,50,75,75,100}。对于这样的集合,RANK()将返回{1、1、3、4、4、6}(请注意,将跳过值2和5),而DENSE_RANK()将返回{1、2、3, 3,4}。