web-dev-qa-db-ja.com

Oracle SQL-列の最高5つの値を取得する方法

選択した数の行だけが最大または最小の列値で返されるクエリをどのように記述しますか。

つまり、給与の高い5人の従業員に関するレポートですか。

16
Trevor

これを行う最良の方法は、分析関数、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を使用する理由はほとんどありません。

25
APC

これを試してください:

SELECT * FROM 
    (SELECT field1, field2 FROM fields order by field1 desc) 
where rownum <= 5

また、rownumの動作の詳細については、 このリソース を参照してください。

11
road242

Oracle 9i +は分析機能を提供します。

すべてにOVER句の使用が必要です。これにより、PARTITION BY句とORDER BY句がROW_NUMBER/RANK/DENSE_RANKを適切に調整できるようになります返される値。

9iより前のバージョンでは、ROWNUMを使用するしか選択肢がありませんでした。これは、ROW_NUMBERlink )を使用するよりも高速です。

4
OMG Ponies

Oracle 12cでは、これはFETCH..FIRSTROWS..ONLYを使用して実現できます。

上位5つの給与を取得します。

 SELECT *
       FROM EMPLOYEES
   ORDER BY SALARY DESC
FETCH FIRST 5 ROWS ONLY;
1
Kaushik Nayak