Sự khác biệt giữa các hàm RANK () và DENSE_RANK () trong orory là gì?


150

Sự khác biệt giữa RANK()DENSE_RANK()chức năng là gì? Làm thế nào để tìm ra mức lương thứ n trong emptblbảng sau ?

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

Nếu trong bảng dữ liệu có nulls, điều gì sẽ xảy ra nếu tôi muốn tìm hiểu nthmức lương?

Câu trả lời:


242

RANK cung cấp cho bạn thứ hạng trong phân vùng được đặt hàng của bạn. Các mối quan hệ được chỉ định cùng thứ hạng, với (các) thứ hạng tiếp theo bị bỏ qua. Vì vậy, nếu bạn có 3 mục ở hạng 2, thứ hạng tiếp theo được liệt kê sẽ được xếp hạng 5.

DENSE_RANK một lần nữa cung cấp cho bạn thứ hạng trong phân vùng được đặt hàng của bạn, nhưng các thứ hạng là liên tiếp. Không có thứ hạng nào được bỏ qua nếu có thứ hạng với nhiều vật phẩm.

Đối với null, nó phụ thuộc vào mệnh đề ORDER BY. Đây là một kịch bản thử nghiệm đơn giản mà bạn có thể chơi để xem điều gì sẽ xảy ra:

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.

Đây là một liên kết đến một lời giải thích tốt và một số ví dụ.


14
ý tưởng rất hay là sử dụng liên kết chọn tất cả từ kép để tạo dữ liệu mẫu mà không cần tạo bất kỳ bảng nào
Jean-Christophe Blanchard

@ Jean-BarsheBlanchard mặc dù bạn có thể dễ dàng sử dụng một valuesmệnh đề.
tự đại diện

1
@Wildcard Trong PG, vâng. Trong Oracle, không . Ít nhất là chưa đến 11. Tôi chưa chạy vào 12 trong prod.
jpmc26

Xóa from dualđể tạo dữ liệu này trong Redshift
Gaurav

4
Ivan, RANK cho tôi một ý tưởng nơi tôi có liên quan đến tất cả những người đi trước tôi. DENSE_RANK cho tôi biết thứ hạng tuyệt đối. Tôi có thể có mức lương cao thứ hai, nhưng có thể có 100 người đi trước tôi. Cái nào tốt hơn phụ thuộc vào câu hỏi tôi đang trả lời.
DCookie

93

Bài viết này ở đây giải thích độc đáo nó. Về cơ bản, bạn có thể nhìn vào nó như vậy:

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;

Những điều trên sẽ mang lại:

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

Nói cách

  • ROW_NUMBER() thuộc tính một giá trị duy nhất cho mỗi hàng
  • RANK() thuộc tính số hàng giống nhau cho cùng một giá trị, để lại "lỗ"
  • DENSE_RANK() thuộc tính số hàng giống nhau cho cùng một giá trị, không để lại "lỗ"

Lỗi: Lỗi SQL: ORA-00923: Không tìm thấy từ khóa TỪ nơi mong đợi
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

rank () : Nó được sử dụng để xếp hạng một bản ghi trong một nhóm các hàng.

dense_rank () : Hàm DENSE_RANK hoạt động giống như hàm RANK ngoại trừ việc nó gán các cấp bậc liên tiếp.

Truy vấn -

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

Đầu ra -

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

Truy vấn -

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

Đầu ra -

+--------+------+-----------+
| 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() -> Được sử dụng để tạo số sê-ri

Dense_rank() sẽ cho thứ hạng liên tục nhưng thứ hạng sẽ bỏ qua thứ hạng trong trường hợp đụng độ thứ hạng.


2

Sự khác biệt duy nhất giữa các hàm RANK () và DENSE_RANK () là trong trường hợp có một cà vạt cà vạt; tức là trong trường hợp nhiều giá trị trong một tập hợp có cùng thứ hạng. Trong các trường hợp như vậy, RANK () sẽ gán các cấp bậc không liên tiếp cho các giá trị trong tập hợp (dẫn đến khoảng cách giữa các giá trị xếp hạng số nguyên khi có một ràng buộc), trong khi DENSE_RANK () sẽ gán các cấp bậc liên tiếp cho các giá trị trong được đặt (do đó sẽ không có khoảng cách giữa các giá trị xếp hạng số nguyên trong trường hợp hòa).

Ví dụ: hãy xem xét tập {25, 25, 50, 75, 75, 100}. Đối với một tập hợp như vậy, RANK () sẽ trả về {1, 1, 3, 4, 4, 6} (lưu ý rằng các giá trị 2 và 5 bị bỏ qua), trong khi DENSE_RANK () sẽ trả về {1,1,2,3, 3,4}.


1

Hàm SQL xếp hạng () tạo thứ hạng của dữ liệu trong tập hợp các giá trị nhưng thứ hạng tiếp theo sau thứ hạng trước đó là row_number của hàng cụ thể đó. Mặt khác, hàm SQL Dense_Rank () tạo số tiếp theo thay vì tạo row_number. Dưới đây là ví dụ SQL sẽ làm rõ khái niệm:

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

Nó sẽ tạo đầu ra sau:

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

Thứ hạng và thứ hạng dày đặc cho thứ hạng trong bộ dữ liệu được phân vùng.

Xếp hạng (): Nó không cung cấp cho bạn các số nguyên liên tiếp.

Dense_rank (): Nó cung cấp cho bạn các số nguyên liên tiếp.

nhập mô tả hình ảnh ở đây

Trong hình trên, thứ hạng của 10008 zip là 2 theo hàm dense_rank () và 24 theo hàm tier () khi nó xem xét row_number.


0

Rank(), Dense_rank(), row_number() Đây là tất cả các chức năng cửa sổ có nghĩa là chúng hoạt động như cửa sổ trên một số đầu vào được đặt hàng lúc đầu. Các cửa sổ này có chức năng khác nhau gắn liền với nó dựa trên yêu cầu. Đây là 3 điều trên:

row_number()

Bắt đầu bằng row_number()cách này tạo thành cơ sở của các chức năng cửa sổ liên quan này. row_number()như tên cho thấy một số duy nhất cho tập hợp các hàng được áp dụng. Tương tự như đưa ra một số sê-ri cho mỗi hàng.

Rank()

Một cuộc lật đổ row_number()có thể nói là rank(). Xếp hạng () được sử dụng để cung cấp cùng một số sê-ri cho các hàng được đặt theo thứ tự trùng lặp nhưng nó vẫn giữ số đếm được giữ nguyên tương tự như row_number()đối với tất cả các số sau khi sao chép thứ hạng () có nghĩa như từ bên dưới, ví dụ như. Đối với dữ liệu 2 row_number () = rank () có nghĩa là cả hai chỉ khác nhau ở dạng trùng lặp.

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

Cuối cùng,

Dense_rank () là phiên bản mở rộng của xếp hạng () vì tên cho thấy mật độ dày đặc của nó bởi vì như bạn có thể thấy từ ví dụ trên xếp hạng () = dense_rank () cho tất cả dữ liệu 1 nhưng chỉ khác với dữ liệu 2, nó khác ở dạng dữ liệu duy trì thứ tự xếp hạng () từ xếp hạng trước () không phải dữ liệu thực tế


0

Sự khác biệt duy nhất giữa các hàm RANK () và DENSE_RANK () là trong trường hợp có một cà vạt cà vạt; tức là trong trường hợp nhiều giá trị trong một tập hợp có cùng thứ hạng. Trong các trường hợp như vậy, RANK () sẽ gán các cấp bậc không liên tiếp cho các giá trị trong tập hợp (dẫn đến khoảng cách giữa các giá trị xếp hạng số nguyên khi có một ràng buộc), trong khi DENSE_RANK () sẽ gán các cấp bậc liên tiếp cho các giá trị trong được đặt (do đó sẽ không có khoảng cách giữa các giá trị xếp hạng số nguyên trong trường hợp hòa).

Ví dụ: hãy xem xét tập {30, 30, 50, 75, 75, 100}. Đối với một tập hợp như vậy, RANK () sẽ trả về {1, 1, 3, 4, 4, 6} (lưu ý rằng các giá trị 2 và 5 bị bỏ qua), trong khi DENSE_RANK () sẽ trả về {1,1,2,3, 3,4}.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.