Monday 19 December 2011

For top N queries

Take care of the difference when there are several same salaries depending on your definition of "top N" (ROW_NUMBER is the same as ROWNUM in Barbara's query)

SQL> select ename, sal,
  2         row_number() over (order by sal desc) "ROW_NUMBER",
  3         rank() over (order by sal desc) "RANK",
  4         dense_rank() over (order by sal desc) "DENSE_RANK"
  5  from emp
  6  /
ENAME             SAL ROW_NUMBER       RANK DENSE_RANK
---------- ---------- ---------- ---------- ----------
KING             5000          1          1          1
FORD             3000          2          2          2
SCOTT            3000          3          2          2
JONES            2975          4          4          3
BLAKE            2850          5          5          4
CLARK            2450          6          6          5
ALLEN            1600          7          7          6
TURNER           1500          8          8          7
MILLER           1300          9          9          8
WARD             1250         10         10          9
MARTIN           1250         11         10          9
ADAMS            1100         12         12         10
JAMES             950         13         13         11
SMITH             800         14         14         12
 
So if you want the employees with the 10th salary, you will have a different answer for each function:





SQL> select ename, sal
  2  from ( select ename, sal,
  3         row_number() over (order by sal desc) "ROW_NUMBER"
  4         from emp )
  5  where "ROW_NUMBER" = 10
  6  /
ENAME             SAL
---------- ----------
WARD             1250

1 row selected.

SQL> select ename, sal
  2  from ( select ename, sal,
  3         rank() over (order by sal desc) "RANK"
  4         from emp )
  5  where "RANK" = 10
  6  /
ENAME             SAL
---------- ----------
WARD             1250
MARTIN           1250

2 rows selected.

SQL> select ename, sal
  2  from ( select ename, sal,
  3         dense_rank() over (order by sal desc) "DENSE_RANK"
  4         from emp )
  5  where "DENSE_RANK" = 10
  6  /
ENAME             SAL
---------- ----------
ADAMS            1100

1 row selected.

No comments: