2010-02-21 33 views

Respuesta

10

prueba este:

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

también echar un vistazo en this resource para una descripción más detallada sobre cómo funciona la ROWNUM.

24

La mejor manera de hacerlo es con funciones analíticas, RANK() o 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() comprime los vacíos cuando hay un empate:

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> 

Qué comportamiento prefiere depende de los requisitos de su negocio.

También existe la función analítica ROW_NUMBER() que podemos usar para devolver un número preciso de filas. Sin embargo, deberíamos evitar el uso de soluciones basadas en el número de fila, a menos que la lógica comercial contenga truncar arbitrariamente el conjunto de resultados en caso de empate. Hay una diferencia entre pedir los cinco valores más altos y los primeros cinco registros ordenados por valores altos

También hay una solución no analítica usando el pseudo-columna ROWNUM. Esto es torpe porque ROWNUM se aplica antes de la cláusula ORDER BY, lo que puede conducir a resultados inesperados. Raramente hay una razón para usar ROWNUM en lugar de ROW_NUMBER() o una de las funciones de clasificación.

+0

Puede usar 'QUALIFY ... <= 5 'en lugar de envolverlo en otro seleccionar. – lins314159

+0

@ lins314159 - QUALIFY no es una construcción compatible con Oracle. – APC

+0

Pensé que sí. ¿O está el enlace hablando de algún otro producto de Oracle? 'Http: //download.oracle.com/docs/cd/E12032_01/doc/epm.921/html_ir_studio/ir_studio-15-36.html' – lins314159

4

Oracle 9i + ofrece funciones analíticas:

Todos requieren el uso de la cláusula de OVER, que permite PARTITION BY y ORDER BY cláusulas para sintonizar correctamente la ROW_NUMBER/RANK/DENSE_RANK valor devuelto.

Antes de 9i, la única opción era trabajar con ROWNUM, que por cierto es más rápido que con ROW_NUMBER (link).

+0

Gracias. La cláusula OVER era nueva para mí. +1 – road242

+0

En realidad, Oracle introdujo las funciones analíticas en 8i, pero solo como en la licencia Enterprise Edition. En 9i llegaron bajo la licencia de Standard Edition. – APC

0

En Oracle 12c, esto se puede lograr usando FETCH..FIRSTROWS..ONLY

a buscar a los 5 mejores salarios más altos.

SELECT * 
     FROM EMPLOYEES 
    ORDER BY SALARY DESC 
FETCH FIRST 5 ROWS ONLY; 
Cuestiones relacionadas