What is the difference between the RANK () and DENSE_RANK () functions in oracle?

What is the difference between the function RANK() and DENSE_RANK() ? How to find the nth salary in the following emptbl table?

 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 

If there are nulls in the table data, what happens if I want to find out nth salary?

+94
sql oracle window-functions
Jun 25 2018-12-12T00:
source share
7 answers

RANK gives you a rating in your ordered section. Links are assigned the same rank, and the next rating is skipped. So, if you have 3 items in rank 2, the next rank will be considered 5.

DENSE_RANK again gives you a rating in your ordered section, but the ranks are consistent. No ranks are omitted if there are rows with several elements.

As for zeros, it depends on the ORDER BY clause. Here is a simple test script that you can play with to find out what will happen:

 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 is a link to a good explanation and some examples.

+162
Jun 25 2018-12-12T00:
source share

This article here perfectly explains this. Essentially, you can look at it as such:

 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; 

The above will give:

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

In words

  • ROW_NUMBER() assigns a unique value to each row
  • RANK() assigns the same line number to the same value, leaving "holes"
  • DENSE_RANK() associates the same line number with the same value without leaving "holes"
+60
Feb 27 '14 at 21:40
source share
 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 
+6
Dec 10 '13 at
source share

rank () : used to rank entries in a row group.

dense_rank () : the DENSE_RANK function acts like a RANK function, except that it assigns consecutive ranks.

Inquiry -

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

Exit -

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

Inquiry -

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

Exit -

 +--------+------+-----------+ | ENAME | SAL | DEN_RANK | +--------+------+-----------+ | SMITH | 800 | 1 | | JAMES | 950 | 2 | | ADAMS | 1100 | 3 | | MARTIN | 1250 | 4 | | WARD | 1250 | 4 | | TURNER | 1500 | 5 | +--------+------+-----------+ 
+4
Aug 05 '16 at 5:28
source share
 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() Used to generate a serial number

Dense_rank() will give a continuous rank, but the rank will skip the rank in the event of a rank collision.

+1
Jul 05 '13 at 12:41
source share

The only difference between the RANK () and DENSE_RANK () functions is when there is a β€œlink”; that is, in cases where several values ​​in a set have the same ranking. In such cases, RANK () assigns disjoint "ranks" to the values ​​in the set (which leads to a gap between the integer ranking values ​​if there is a relationship), while DENSE_RANK () assigns consecutive ranks to the values ​​in set (therefore, there will be no spaces between integer ranking values ​​in the case of bindings).

For example, consider the set {25, 25, 50, 75, 75, 100}. For such a set, RANK () will return {1, 1, 3, 4, 4, 6} (note that the values ​​2 and 5 are omitted), while DENSE_RANK () will return {1,1,2,3, 3,4 }.

+1
Apr 29 '16 at 7:34
source share

The SQL Rank () function generates a data rank in an ordered set of values, but the next rank after the previous rank is the row number of that particular row. On the other hand, the SQL Dense_Rank () function generates the next number instead of row_number. The following is an example of SQL that will clarify the concept:

 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 

It will generate the following result:

 ---------------------------- 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
Jul 20 '18 at 8:42
source share



All Articles