これを行う最良の方法は、分析関数、RANK()または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()は、同点の場合にギャップを圧縮します:
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>
どの動作を好むかは、ビジネス要件によって異なります。
正確な行数を返すために使用できるROW_NUMBER()分析関数もあります。ただし、同点の場合にビジネスロジックが結果セットを任意に切り捨てることができない限り、行番号に基づくソリューションの使用は避ける必要があります。 5つの最高値を求めることには違いがあります 高い値でソートされた最初の5つのレコード
ROWNUM疑似列を使用した非分析ソリューションもあります。 ROWNUMがORDERBY句の前に適用され、予期しない結果が生じる可能性があるため、これは不格好です。 ROW_NUMBER()またはランキング関数の1つの代わりにROWNUMを使用する理由はめったにありません。