ChatGPT解决这个技术问题 Extra ChatGPT

oracle 中的 RANK() 和 DENSE_RANK() 函数有什么区别?

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的薪水会怎样?


A
AlSub

RANK() 为您提供有序分区内的排名。平局被分配相同的排名,下一个排名被跳过。因此,如果您在 2 级有 3 个项目,则列出的下一个等级将是 5 级。

DENSE_RANK() 再次为您提供有序分区内的排名,但排名是连续的。如果有多个项目的排名,则不会跳过排名。

至于空值,它取决于 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 来一个很好的解释和一些例子。


使用 select union all from dual 来生成样本数据而不创建任何表的好主意
@Jean-ChristopheBlanchard 尽管您可以轻松地使用 values 子句。
@Wildcard 在 PG 中,是的。在甲骨文中,没有。至少在 11 岁之前没有。我还没有在 prod 中遇到 12 岁。
删除 from dual 以在 Redshift 中生成此数据
Ivan, RANK 让我知道我相对于我前面的所有人的位置。 DENSE_RANK 告诉我绝对排名。我可能有第二高的薪水,但可能有100人在我前面。哪个更好取决于我要回答的问题。
L
Lukas Eder

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() 将相同的行号赋予相同的值,留下“漏洞”

DENSE_RANK() 将相同的行号赋予相同的值,不会留下“漏洞”


错误:SQL 错误:ORA-00923:在预期的地方找不到 FROM 关键字
S
Shine

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 |
+--------+------+-----------+

A
Anant_00
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

H
Harinath
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() 将给出连续排名,但 Rank() 将在排名冲突的情况下跳过排名。


S
Salman Lone

RANK() 和 DENSE_RANK() 函数之间的唯一区别在于存在“平局”的情况;即,在一组中的多个值具有相同排名的情况下。在这种情况下,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}。


B
Brijesh Kumar Tripathi

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

H
Himanshu

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() = dense_rank() 但只是对于数据 2,它的形式不同维护前一个 rank() 的 rank() 顺序,而不是实际数据


T
Tutu Kumari

Rank and Dense rank 给出分区数据集中的排名。

Rank() :它不会给你连续的整数。

Dense_rank() :它给你连续的整数。

https://i.stack.imgur.com/fbv8Z.png

在上图中,考虑 row_number 时,10008 zip 的排名是 2,dense_rank() 函数和 rank() 函数的 24。


r
rjose

RANK() 和 DENSE_RANK() 函数之间的唯一区别在于存在“平局”的情况;即,在一组中的多个值具有相同排名的情况下。在这种情况下,RANK() 将为集合中的值分配不连续的“排名”(导致出现平局时整数排名值之间的差距),而 DENSE_RANK() 将为集合中的值分配连续的排名设置(因此在平局的情况下整数排名值之间不会有差距)。

例如,考虑集合 {30, 30, 50, 75, 75, 100}。对于这样的集合,RANK() 将返回 {1, 1, 3, 4, 4, 6}(注意值 2 和 5 被跳过),而 DENSE_RANK() 将返回 {1,1,2,3, 3,4}。