選択した数の行だけが最大または最小の列値で返されるクエリをどのように記述しますか。
つまり、給与の高い5人の従業員に関するレポートですか。
これを行う最良の方法は、分析関数、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がORDER BY句の前に適用され、予期しない結果が生じる可能性があるため、これは不格好です。 ROW_NUMBER()またはランキング関数の1つではなくROWNUMを使用する理由はほとんどありません。
これを試してください:
SELECT * FROM
(SELECT field1, field2 FROM fields order by field1 desc)
where rownum <= 5
また、rownumの動作の詳細については、 このリソース を参照してください。
Oracle 9i +は分析機能を提供します。
すべてにOVER
句の使用が必要です。これにより、PARTITION BY
句とORDER BY
句がROW_NUMBER
/RANK
/DENSE_RANK
を適切に調整できるようになります返される値。
9iより前のバージョンでは、ROWNUM
を使用するしか選択肢がありませんでした。これは、ROW_NUMBER
( link )を使用するよりも高速です。
Oracle 12cでは、これはFETCH..FIRST
ROWS..ONLY
を使用して実現できます。
上位5つの給与を取得します。
SELECT *
FROM EMPLOYEES
ORDER BY SALARY DESC
FETCH FIRST 5 ROWS ONLY;