Using Rank() and DENSE_RANK() and ROW_NUMBER() functions:
Table and
data creation:
CREATE TABLE emptest
(eno VARCHAR2(20) primary key,ename
VARCHAR2(20),salary NUMBER(10,2)
);COMMIT;
insert into
emptest values('E101','
insert into
emptest values('E102','Gladiator','3600');
insert into
emptest values('E222','Hellboy','4500');
insert into
emptest values('E345','Spider Man','3100');
insert into
emptest values('E631','
insert into
emptest values('E761','Harry Potter','3300');
commit;
View Data:
SELECT * FROM emptest;
|
ENO |
ENAME |
SALARY |
|
E101 |
|
3000 |
|
E102 |
Gladiator |
3600 |
|
E222 |
Hellboy |
4500 |
|
E345 |
Spider Man |
3100 |
|
E631 |
|
3300 |
|
E761 |
Harry Potter |
3300 |
Scenario #1: Display the ranks for each record based on ename. If
more than one records is having same ename, it assigns different rank to each
record.
SELECT eno,ename,salary,rank from (select
eno,ename,salary,RANK() OVER(PARTITION BY ename ORDER BY salary desc NULLS
LAST) AS Rank FROM emptest)
|
ENO |
ENAME |
SALARY |
RANK |
|
E102 |
Gladiator |
3600 |
1 |
|
E761 |
Harry Potter |
3300 |
1 |
|
E222 |
Hellboy |
4500 |
1 |
|
E631 |
|
3300 |
1 |
|
E101 |
|
3000 |
2 |
|
E345 |
Spider Man |
3100 |
1 |
Scenario
#2: Display the
ranks for each record based on salary. If more than one records is having same
salary, it assigns different rank to each record.
SELECT eno,ename,salary,rank from (select eno,ename,salary,RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank FROM emptest)
If same rank(eg:rank 3) is assigned to say 2 records, then
next rank number will be 5 only. If you would like to have continuous number
use DENSE_RANK(). See Scenario#3.
|
ENO |
ENAME |
SALARY |
RANK |
|
E222 |
Hellboy |
4500 |
1 |
|
E102 |
Gladiator |
3600 |
2 |
|
E761 |
Harry Potter |
3300 |
3 |
|
E631 |
Ravi Sambangi |
3300 |
3 |
|
E345 |
Spider Man |
3100 |
5 |
|
E101 |
Ravi Sambangi |
3000 |
6 |
Scenario
#3: Display the
ranks for each record based on salary. If more than one records is having same
salary, it assigns different rank to each record.
SELECT eno,ename,salary,rank from (select eno,ename,salary,DENSE_RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank FROM emptest)
|
ENO |
ENAME |
SALARY |
RANK |
|
E222 |
Hellboy |
4500 |
1 |
|
E102 |
Gladiator |
3600 |
2 |
|
E761 |
Harry Potter |
3300 |
3 |
|
E631 |
Ravi Sambangi |
3300 |
3 |
|
E345 |
Spider Man |
3100 |
4 |
|
E101 |
Ravi Sambangi |
3000 |
5 |
Note: Even though the same rank(eg:rank 3) is assigned to say
2 records, the next rank number is immediate number.
Scenario #4: Display all the records from the emptest table with the below constrains
1. If more than one employee having the same name, display only one employee information who is getting more salary.
SELECT
eno,ename,salary,rank from (select eno,ename,salary,RANK() OVER(PARTITION BY
ename ORDER BY salary desc NULLS LAST) AS Rank FROM emptest) where rank=1
|
ENO |
ENAME |
SALARY |
|
E102 |
Gladiator |
3600 |
|
E761 |
Harry Potter |
3300 |
|
E222 |
Hellboy |
4500 |
|
E631 |
Ravi Sambangi |
3300 |
|
E345 |
Spider Man |
3100 |
Scenario
#5:
Display the employee record who is getting 3rd highest salary
(Using RANK())
There could be some risk using RANK() function in
below queries.
SELECT eno,ename,salary,rank from (select
eno,ename,salary,RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank FROM
emptest) where rank=3
|
ENO |
ENAME |
SALARY |
RANK |
|
E631 |
Ravi Sambangi |
3300 |
3 |
|
E761 |
Harry Potter |
3300 |
3 |
Display
the employee record who is getting 4th highest salary.
SELECT eno,ename,salary,rank from (select
eno,ename,salary,RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank FROM
emptest) where rank=4
|
ENO |
ENAME |
SALARY |
RANK |
No Records Found
Reason: RANK() function won't have continuous numbers
sometimes. Refer Scenario#2 output
to see the ranks allocated to all the rows.
To escape from above problems, use DENSE_RANK() which will have continuous numbers. See Scenario#3 for more details on DENSE_RANK()
Scenario
#6:
Display the employee record who is getting 3rd highest salary
(Using DENSE_RANK())
SELECT eno,ename,salary,rank from (select
eno,ename,salary,DENSE_RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank
FROM emptest) where rank=3
|
ENO |
ENAME |
SALARY |
RANK |
|
E631 |
Ravi Sambangi |
3300 |
3 |
|
E761 |
Harry Potter |
3300 |
3 |
Got the same result as RANK(), but below query brings
different result than RANK()
Display the employee record who is getting 4th highest salary
(Using DENSE_RANK())
SELECT eno,ename,salary,rank from (select
eno,ename,salary,DENSE_RANK() OVER(ORDER BY salary desc NULLS LAST) AS Rank
FROM emptest) where rank=4
|
ENO |
ENAME |
SALARY |
RANK |
|
E345 |
Spider Man |
3100 |
4 |
Got the 4th highest salary records but if we use RANK() we
will not get it.
Additional
Item:
Assume you have another record in your database table say: insert into emptest values('E632','
If multiple records are having same name then, consider only
one record based on highest salary. If more than one record is having same name
and same highest salary for that name, just consider only one record, then we
have to use ROW_NUMBER() function.
SELECT eno,ename,salary,rank from (select
eno,ename,salary,ROW_NUMBER() OVER(PARTITION BY ename ORDER BY salary desc
NULLS LAST) AS Rank FROM emptest) where rank=1;
|
EID |
ENAME |
SALARY |
RANK |
|
E102 |
Gladiator |
3600 |
1 |
|
E761 |
Harry
Potter |
3300 |
1 |
|
E222 |
Hellboy |
4500 |
1 |
|
E631 |
Ravi
Sambangi |
3300 |
1 |
|
E345 |
Spider
Man |
3100 |
1 |