De beste manier om dit te doen is met analytische functies, RANK() of 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() comprimeert de gaten wanneer er een gelijkspel is:
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>
Welk gedrag u verkiest, hangt af van uw zakelijke vereisten.
Er is ook de analytische functie ROW_NUMBER() die we kunnen gebruiken om een precies aantal rijen te retourneren. We moeten echter vermijden om oplossingen te gebruiken op basis van rijnummer, tenzij de bedrijfslogica graag willekeurig de resultatenset afkapt in het geval van een gelijkspel. Er is een verschil tussen vragen om de vijf hoogste waarden en de eerste vijf records gesorteerd op hoge waarden
Er is ook een niet-analytische oplossing die de ROWNUM-pseudokolom gebruikt. Dit is onhandig omdat ROWNUM wordt toegepast vóór de ORDER BY-component, wat tot onverwachte resultaten kan leiden. Er is zelden een reden om ROWNUM te gebruiken in plaats van ROW_NUMBER() of een van de rangschikkingsfuncties.