Apa perbedaan antara fungsi RANK () dan DENSE_RANK () di oracle?


150

Apa perbedaan antara RANK()dan DENSE_RANK()fungsinya? Bagaimana cara mengetahui gaji ke-n dalam emptbltabel berikut ?

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

Jika dalam tabel memiliki data nulls, apa yang akan terjadi jika saya ingin mengetahui nthgaji?

Jawaban:


242

PERINGKAT memberi Anda peringkat dalam partisi yang Anda pesan. Dasi diberi peringkat yang sama, dengan peringkat berikutnya dilewati. Jadi, jika Anda memiliki 3 item di peringkat 2, peringkat berikutnya yang terdaftar akan menjadi peringkat 5.

DENSE_RANK lagi memberi Anda peringkat dalam partisi yang Anda pesan, tetapi peringkatnya berturut-turut. Tidak ada peringkat yang dilewati jika ada peringkat dengan beberapa item.

Adapun nol, itu tergantung pada klausa ORDER BY. Berikut ini adalah skrip tes sederhana yang dapat Anda mainkan untuk melihat apa yang terjadi:

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.

Berikut tautan ke penjelasan yang bagus dan beberapa contoh.


14
ide yang sangat bagus untuk menggunakan serikat pilih semua dari dua untuk menghasilkan data sampel tanpa membuat tabel apa pun
Jean-Christophe Blanchard

@ Jean-ChristopheBlanchard meskipun Anda bisa dengan mudah menggunakan valuesklausa.
Wildcard

1
@ Kartu Memori Di PG, ya. Di Oracle, tidak . Setidaknya bukan pada 11. Aku belum bertemu dengan 12 dalam prod belum.
jpmc26

Hapus from dualuntuk menghasilkan data ini di Redshift
Gaurav

4
Ivan, RANK memberi saya ide di mana saya relatif terhadap semua yang ada di depan saya. DENSE_RANK memberi tahu saya peringkat absolut. Saya mungkin memiliki gaji tertinggi kedua, tetapi mungkin ada 100 orang di depan saya. Mana yang lebih baik tergantung pada pertanyaan yang saya jawab.
DCookie

93

Artikel ini dengan baik menjelaskannya. Pada dasarnya, Anda dapat melihatnya seperti ini:

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;

Di atas akan menghasilkan:

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

Dalam kata kata

  • ROW_NUMBER() atribut nilai unik untuk setiap baris
  • RANK() atribut nomor baris yang sama dengan nilai yang sama, meninggalkan "lubang"
  • DENSE_RANK() atribut nomor baris yang sama dengan nilai yang sama, tidak meninggalkan "lubang"

Kesalahan: SQL Kesalahan: ORA-00923: DARI kata kunci yang tidak ditemukan di tempat yang diharapkan
zloctb

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

8

pangkat() : Ini digunakan untuk memberi peringkat catatan dalam kelompok baris.

dense_rank () : Fungsi DENSE_RANK bertindak seperti fungsi RANK kecuali bahwa ia memberikan peringkat berurutan.

Permintaan -

select 
    ENAME,SAL,RANK() over (order by SAL) RANK
from 
    EMP;

Keluaran -

+--------+------+------+
| ENAME  | SAL  | RANK |
+--------+------+------+
| SMITH  |  800 |    1 |
| JAMES  |  950 |    2 |
| ADAMS  | 1100 |    3 |
| MARTIN | 1250 |    4 |
| WARD   | 1250 |    4 |
| TURNER | 1500 |    6 |
+--------+------+------+

Permintaan -

select 
    ENAME,SAL,dense_rank() over (order by SAL) DEN_RANK
from 
    EMP;

Keluaran -

+--------+------+-----------+
| ENAME  | SAL  |  DEN_RANK |
+--------+------+-----------+
| SMITH  |  800 |         1 |
| JAMES  |  950 |         2 |
| ADAMS  | 1100 |         3 |
| MARTIN | 1250 |         4 |
| WARD   | 1250 |         4 |
| TURNER | 1500 |         5 |
+--------+------+-----------+

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() -> Digunakan untuk menghasilkan nomor seri

Dense_rank() akan memberikan peringkat terus menerus tetapi peringkat akan melewati peringkat dalam kasus clash of rank.


2

Satu-satunya perbedaan antara fungsi RANK () dan DENSE_RANK () adalah dalam kasus di mana ada "dasi"; yaitu, dalam kasus di mana beberapa nilai dalam satu set memiliki peringkat yang sama. Dalam kasus seperti itu, RANK () akan menetapkan "peringkat" non-berurutan ke nilai-nilai dalam set (menghasilkan kesenjangan antara nilai peringkat integer ketika ada dasi), sedangkan DENSE_RANK () akan menetapkan peringkat berturut-turut ke nilai-nilai dalam set (jadi tidak akan ada kesenjangan antara nilai peringkat integer dalam kasus seri).

Misalnya, pertimbangkan set {25, 25, 50, 75, 75, 100}. Untuk set semacam itu, RANK () akan mengembalikan {1, 1, 3, 4, 4, 6} (perhatikan bahwa nilai 2 dan 5 dilewati), sedangkan DENSE_RANK () akan mengembalikan {1,1,2,3, 3,4}.


1

Peringkat () Fungsi SQL menghasilkan peringkat data dalam kumpulan nilai yang diurutkan, tetapi peringkat berikutnya setelah peringkat sebelumnya adalah row_number dari baris tersebut. Di sisi lain, fungsi Dense_Rank () SQL menghasilkan nomor berikutnya daripada menghasilkan row_number. Di bawah ini adalah contoh SQL yang akan menjelaskan konsep:

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

Ini akan menghasilkan output sebagai berikut:

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

0

Rank dan Dense rank memberikan peringkat dalam dataset yang dipartisi.

Rangking (): Ini tidak memberi Anda angka integer berurutan.

Dense_rank (): Ini memberi Anda angka integer berurutan.

masukkan deskripsi gambar di sini

Dalam gambar di atas, pangkat 10008 zip adalah fungsi 2 oleh dense_rank () dan fungsi 24 oleh peringkat () karena dianggap sebagai row_number.


0

Rank(), Dense_rank(), row_number() Ini semua adalah fungsi jendela yang berarti mereka bertindak sebagai jendela pada beberapa input yang diatur pada awalnya. Jendela-jendela ini memiliki fungsi berbeda yang dilampirkan berdasarkan kebutuhan. Inilah 3 di atas:

row_number()

Dimulai dengan row_number()ini sebagai dasar dari fungsi-fungsi jendela terkait ini. row_number()seperti namanya memberikan nomor unik untuk set baris yang telah diterapkan. Mirip dengan memberikan nomor seri untuk setiap baris.

Rank()

Subversi dari row_number()dapat dikatakan sebagai rank(). Rank () digunakan untuk memberikan nomor seri yang sama dengan baris-baris yang dipesan yang merupakan duplikat tetapi tetap menjaga jumlah dipertahankan sebagai mirip dengan row_number()untuk semua orang setelah duplikat peringkat () yang berarti dari bawah misalnya misalnya. Untuk data 2 row_number () = rank () yang berarti keduanya hanya berbeda dalam bentuk duplikat.

Data row_number() rank() dense_rank() 
    1         1                    1       1
    1         2                    1       1
    1         3                    1       1
    2         4                    4       2

Akhirnya,

Dense_rank () adalah versi lanjutan dari peringkat () karena namanya menunjukkan kepadatannya karena seperti yang Anda lihat dari contoh peringkat di atas () = dense_rank () untuk semua data 1 tetapi hanya untuk data 2 berbeda dalam bentuk yang mempertahankan urutan peringkat () dari peringkat sebelumnya () bukan data aktual


0

Satu-satunya perbedaan antara fungsi RANK () dan DENSE_RANK () adalah dalam kasus di mana ada "dasi"; yaitu, dalam kasus di mana beberapa nilai dalam satu set memiliki peringkat yang sama. Dalam kasus seperti itu, RANK () akan menetapkan "peringkat" non-berurutan ke nilai-nilai dalam set (menghasilkan kesenjangan antara nilai peringkat integer ketika ada dasi), sedangkan DENSE_RANK () akan menetapkan peringkat berturut-turut ke nilai-nilai dalam set (jadi tidak akan ada kesenjangan antara nilai peringkat integer dalam kasus seri).

Misalnya, pertimbangkan set {30, 30, 50, 75, 75, 100}. Untuk set semacam itu, RANK () akan mengembalikan {1, 1, 3, 4, 4, 6} (perhatikan bahwa nilai 2 dan 5 dilewati), sedangkan DENSE_RANK () akan mengembalikan {1,1,2,3, 3,4}.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.