web-dev-qa-db-ja.com

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給与を調べたい場合はどうなりますか?

129
user1357722

ランクはあなたの順序付けられたパーティション内のランキングをあなたに与えます。ネクタイには同じランクが割り当てられ、次のランクはスキップされます。したがって、ランク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.

これは良い説明といくつかの例へのリンク です。

204
DCookie

この記事では、このトピックについて詳しく説明しています。 基本的に、そのように考えることができます。

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()は同じ行番号を同じ値に属性付けし、 "穴"を残さない
77
Lukas Eder
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
9
Anant_00

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 |
+--------+------+-----------+
7
Shine
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はランクをスキップします。

2

RANK()関数とDENSE_RANK()関数の唯一の違いは、「tie」がある場合です。すなわち、セット内の複数の値が同じランキングを持つ場合。このような場合、RANK()はセット内の値に非連続の「ランク」を割り当て(タイがある場合は整数のランク値の間にギャップが生じます)、DENSE_RANK()は連続のランクをにセットします。設定します(したがって、tieの場合は整数のランク付け値の間にギャップはありません)。

例えば、集合{25、25、50、75、75、100}を考えてみましょう。そのようなセットでは、RANK()は{1、1、3、4、4、6}を返します(値2と5はスキップされます)が、DENSE_RANK()は{1,1,2,3、...を返します。 3,4}。

2
Salman Lone

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

Rank and Dense rankは、区分データセット内のランクを示します。

Rank():それはあなたに連続した整数を与えません。

Dense_rank():それはあなたに連続した整数を与えます。

enter image description here

上の図で、10008 Zipのランクは、row_numberを考慮して、dense_rank()関数で2、rank()関数で24です。

0
Tutu Kumari