Det bästa sättet att göra detta är med analytiska funktioner, RANK() eller 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() komprimerar mellanrummen när det är oavgjort:
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>
Vilket beteende du föredrar beror på dina affärskrav.
Det finns också analysfunktionen ROW_NUMBER() som vi kan använda för att returnera ett exakt antal rader. Vi bör dock undvika att använda lösningar baserade på radnummer såvida inte affärslogiken gärna godtyckligt trunkerar resultatuppsättningen i händelse av oavgjort. Det är skillnad på att fråga efter de fem högsta värdena och de första fem posterna sorterade efter höga värden
Det finns också en icke-analytisk lösning som använder pseudokolumnen ROWNUM. Detta är klumpigt eftersom ROWNUM tillämpas före ORDER BY-satsen, vilket kan leda till oväntade resultat. Det finns sällan någon anledning att använda ROWNUM istället för ROW_NUMBER() eller någon av rankningsfunktionerna.