How do you write a query where only a select number of rows are returned with either the highest or lowest column value.
i.e. A report with the 5 highest salaried employees?
How do you write a query where only a select number of rows are returned with either the highest or lowest column value.
i.e. A report with the 5 highest salaried employees?
Try this one:
SELECT * FROM
(SELECT field1, field2 FROM fields order by field1 desc)
where rownum < 5
Also take a look on this resource for a more detailed description on how rownum works.
The best way to do this is with analytic functions, RANK() or DENSE_RANK() ...
SQL> select * from (
2 select empno
3 , sal
4 , rank() over (order by sal desc) as rnk
5 from emp)
6 where rnk <= 5
7 /
EMPNO SAL RNK
---------- ---------- ----------
7839 5000 1
7788 3000 2
7902 3000 2
7566 2975 4
8083 2850 5
7698 2850 5
6 rows selected.
SQL>
DENSE_RANK() compresses the gaps when there is a tie:
SQL> select * from (
2 select empno
3 , sal
4 , dense_rank() over (order by sal desc) as rnk
5 from emp)
6 where rnk <= 5
7 /
EMPNO SAL RNK
---------- ---------- ----------
7839 5000 1
7788 3000 2
7902 3000 2
7566 2975 3
8083 2850 4
7698 2850 4
8070 2500 5
7 rows selected.
SQL>
Which behaviour you prefer depends upon your business requirements.
Avoid using solutions based on row number unless you want to arbitrarily truncate your resultset in the event of a tie. There is a difference between asking for the five highest values and the first five records sorted by high values
Oracle 9i+ provides analytic functions:
All require the use of the OVER
clause, which allows PARTITION BY
and ORDER BY
clauses to properly tune the ROW_NUMBER
/RANK
/DENSE_RANK
value returned.
Prior to 9i, the only option was to work with ROWNUM
- which incidentally is faster than using ROW_NUMBER
(link).