¿Cómo limito el número de filas devueltas por una consulta de Oracle después de realizar el pedido?
¿Hay alguna manera de hacer que una Oracle
consulta se comporte como si contuviera una limit
cláusula MySQL?
En MySQL, puedo hacer esto:
select *
from sometable
order by name
limit 20,10
para obtener las filas 21 a 30 (omita las primeras 20, dé las siguientes 10). Las filas se seleccionan después de order by
, por lo que realmente comienza en el nombre número 20 alfabéticamente.
En Oracle, lo único que la gente menciona es la rownum
pseudocolumna, pero se evalúa antes order by
, lo que significa esto:
select *
from sometable
where rownum <= 10
order by name
devolverá un conjunto aleatorio de diez filas ordenadas por nombre, que normalmente no es lo que quiero. Tampoco permite especificar un desplazamiento.
Puedes usar una subconsulta para esto como
select *
from
( select *
from emp
order by sal desc )
where ROWNUM <= 5;
Eche también un vistazo al tema Sobre ROWNUM y limitación de resultados en Oracle/AskTom para obtener más información.
Actualización : para limitar el resultado con límites superiores e inferiores, las cosas se hinchan un poco más con
select * from
( select a.*, ROWNUM rnum from
( <your_query_goes_here, with order by> ) a
where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum >= :MIN_ROW_TO_FETCH;
(Copiado del artículo de AskTom especificado)
Actualización 2 : a partir de Oracle 12c (12.1), hay una sintaxis disponible para limitar filas o comenzar en desplazamientos.
-- only get first 10 results
SELECT *
FROM sometable
ORDER BY name
FETCH FIRST 10 ROWS ONLY;
-- get result rows 20-30
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Vea esta respuesta para más ejemplos. Gracias a Krumia por la pista.
A partir de Oracle 12c R1 (12.1), existe una cláusula de limitación de filas . No utiliza LIMIT
una sintaxis familiar, pero puede hacer mejor el trabajo con más opciones. Puede encontrar la sintaxis completa aquí . (Lea también más sobre cómo funciona esto internamente en Oracle en esta respuesta ).
Para responder a la pregunta original, aquí está la consulta:
SELECT *
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
(Para versiones anteriores de Oracle, consulte otras respuestas en esta pregunta)
Ejemplos:
Los siguientes ejemplos se citaron de la página vinculada , con la esperanza de evitar que el vínculo se pudra.
Configuración
CREATE TABLE rownum_order_test (
val NUMBER
);
INSERT ALL
INTO rownum_order_test
SELECT level
FROM dual
CONNECT BY level <= 10;
COMMIT;
¿Qué hay en la mesa?
SELECT val
FROM rownum_order_test
ORDER BY val;
VAL
----------
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
20 rows selected.
Obtener las primeras N
filas
SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;
VAL
----------
10
10
9
9
8
5 rows selected.
Get first N
rows, if N
th row has ties, get all the tied rows
SELECT val
FROM rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES;
VAL
----------
10
10
9
9
8
8
6 rows selected.
Top x
% of rows
SELECT val
FROM rownum_order_test
ORDER BY val
FETCH FIRST 20 PERCENT ROWS ONLY;
VAL
----------
1
1
2
2
4 rows selected.
Using an offset, very useful for pagination
SELECT val
FROM rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;
VAL
----------
3
3
4
4
4 rows selected.
You can combine offset with percentages
SELECT val
FROM rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 20 PERCENT ROWS ONLY;
VAL
----------
3
3
4
4
4 rows selected.