¿Hay alguna manera de hacer que una Oracle
consulta se comporte como si contuviera una MySQL limit
cláusula?
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 alfabéticamente en el vigésimo nombre.
En Oracle
, lo único que la gente menciona es la rownum
pseudo-columna, 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 generalmente no es lo que quiero. Tampoco permite especificar un desplazamiento.
sql
oracle
pagination
sql-limit
Mathieu Longtin
fuente
fuente
ORDER BY
. Ese es el punto de ordenar primero. Si los datos subyacentes cambian y su conjunto de resultados cambia debido a ello, ¿por qué no mostrar al usuario los resultados actualizados en lugar de la información desactualizada? Además, la gestión estatal es una plaga que debe evitarse tanto como sea posible. Es una fuente constante de complicaciones y errores; Es por eso que funcional se está volviendo tan popular. ¿Y cuándo sabrías caducar todo el conjunto de resultados en la memoria? En la web, no tienes forma de saber cuándo se va el usuario.Respuestas:
A partir de Oracle 12c R1 (12.1), no es una fila cláusula limitante . No utiliza una
LIMIT
sintaxis familiar , pero puede hacer el trabajo mejor con más opciones. Puede encontrar la sintaxis completa aquí . (También lea más sobre cómo funciona esto internamente en Oracle en esta respuesta ).Para responder la pregunta original, aquí está la consulta:
(Para versiones anteriores de Oracle, consulte otras respuestas en esta pregunta)
Ejemplos:
Los siguientes ejemplos fueron citados de la página vinculada , con la esperanza de prevenir la pudrición de enlaces.
Preparar
¿Qué hay en la mesa?
Consigue las primeras
N
filasObtenga las primeras
N
filas, siN
la fila tiene empates, obtenga todas las filas atadasx
% Superior de filasUsando un desplazamiento, muy útil para la paginación
Puedes combinar offset con porcentajes
fuente
OFFSET FETCH
sintaxis es un azúcar de sintaxis. DetallesPuede usar una subconsulta para esto como
Consulte también el tema En ROWNUM y los resultados limitantes en Oracle / AskTom para obtener más información.
Actualización : para limitar el resultado con los límites inferior y superior, las cosas se hinchan un poco más con
(Copiado del artículo AskTom especificado)
Actualización 2 : a partir de Oracle 12c (12.1) hay una sintaxis disponible para limitar las filas o comenzar en las compensaciones.
Vea esta respuesta para más ejemplos. Gracias a Krumia por la pista.
fuente
Hice algunas pruebas de rendimiento para los siguientes enfoques:
Asktom
Analítico
Alternativa corta
Resultados
La tabla tenía 10 millones de registros, la clasificación estaba en una fila de fecha y hora no indexada:
Seleccionar las primeras 10 filas tomó:
Seleccionar filas entre 100,000 y 100,010:
Selección de filas entre 9,000,000 y 9,000,010:
fuente
BETWEEN
es solo una abreviatura de>= AND <=
( stackoverflow.com/questions/4809083/between-clause-versus-and )offset
sintaxis tiene el mismo plan y rendimiento que el enfoque analítico.Una solución analítica con una sola consulta anidada:
Rank()
podría sustituirseRow_Number()
pero podría devolver más registros de los que espera si hay valores duplicados para el nombre.fuente
rank()
, también vale la pena señalardense_rank()
qué puede ser más útil para el control de salida, ya que este último no "omite" los números, mientras querank()
puede. En cualquier caso para esta preguntarow_number()
es el más adecuado. Otra no es que esta técnica es aplicable a cualquier base de datos que admita las funciones mencionadas.En Oracle 12c (consulte la cláusula de limitación de filas en la referencia de SQL ):
fuente
LIMIT
en SQL: 2008, tuvieron que sacar una hoja del libro de Microsoft y romper el estándar.LIMIT ... OFFSET
LIMIT n, m
(Ver mi respuesta). Por otra parte, Oracle debería haberse implementadoLIMIT n, m
como azúcar sintáctico, ya que es equivalente aOFFSET n ROWS FETCH NEXT m ROWS ONLY
.Las consultas de paginación con pedidos son realmente complicadas en Oracle.
Oracle proporciona una pseudocolumna ROWNUM que devuelve un número que indica el orden en que la base de datos selecciona la fila de una tabla o conjunto de vistas unidas.
ROWNUM es una pseudocolumna que mete en problemas a muchas personas. Un valor ROWNUM no se asigna permanentemente a una fila (este es un malentendido común). Puede ser confuso cuando se asigna un valor ROWNUM. Se asigna un valor ROWNUM a una fila después de pasar los predicados de filtro de la consulta pero antes de la agregación u ordenación de la consulta .
Además, un valor ROWNUM se incrementa solo después de ser asignado.
Es por eso que la consulta de seguimiento no devuelve filas:
La primera fila del resultado de la consulta no pasa el predicado ROWNUM> 1, por lo que ROWNUM no se incrementa a 2. Por esta razón, ningún valor ROWNUM obtiene más de 1, por lo tanto, la consulta no devuelve filas.
La consulta definida correctamente debería verse así:
Obtenga más información sobre las consultas de paginación en mis artículos en el blog de Vertabelo :
fuente
SQL estándar
Como expliqué en este artículo , el estándar SQL: 2008 proporciona la siguiente sintaxis para limitar el conjunto de resultados de SQL:
Oracle 11g y versiones anteriores
Antes de la versión 12c, para obtener los registros Top-N, tenía que usar una tabla derivada y la pseudocolumna ROWNUM:
fuente
Menos declaraciones SELECT. Además, consume menos rendimiento. Créditos a: [email protected]
fuente
Como una extensión de la respuesta aceptada, Oracle utiliza internamente
ROW_NUMBER/RANK
funciones.OFFSET FETCH
La sintaxis es un azúcar de sintaxis.Se pudo observar mediante el
DBMS_UTILITY.EXPAND_SQL_TEXT
procedimiento:Preparación de muestra:
Consulta:
es regular:
demostración de violín db <>
Obteniendo texto SQL expandido:
WITH TIES
se expande comoRANK
:y compensación:
fuente
Si no está en Oracle 12C, puede usar la consulta TOP N como se muestra a continuación.
Incluso puede mover esto de la cláusula con la cláusula de la siguiente manera
Aquí en realidad estamos creando una vista en línea y renombrando rownum como rnum. Puede usar rnum en la consulta principal como criterio de filtro.
fuente
ORDER BY
y el porrownum
separado. Básicamente, creé una subconsulta que tenía laORDER BY
cláusula .rownum
debería estar fuera de una subconsulta.Comencé a prepararme para el examen Oracle 1z0-047, validado contra 12c. Mientras me preparaba, me encontré con una mejora de 12c conocida como 'OBTENER PRIMERO' Le permite buscar filas / filas de límite según su conveniencia. Hay varias opciones disponibles con él.
Ejemplo:
fuente
mayores que los valores averiguar
menos de los valores averiguar
fuente
ROW_NUMBER()
solución basada ya había sido publicado por Leigh Riffel. En adicción hay errores de sintaxis en el código que se muestra.Para cada fila devuelta por una consulta, la pseudocolumna ROWNUM devuelve un número que indica el orden en que Oracle selecciona la fila de una tabla o conjunto de filas unidas. La primera fila seleccionada tiene un ROWNUM de 1, la segunda tiene 2, y así sucesivamente.
He implementado esto en el
oracle
servidor11.2.0.1.0
fuente
En el caso de SQL-Developer, recupera automáticamente solo las primeras 50 filas. ¡Y si nos desplazamos hacia abajo, obtiene otras 50 filas y así sucesivamente!
¡Por lo tanto, no necesitamos definir, en el caso de la herramienta sql-developer!
fuente
En oráculo
VAL
5 filas seleccionadas.
SQL>
fuente
(no probado) algo como esto puede hacer el trabajo
También está el rango de función analítica, que puede usar para ordenar por.
fuente
Igual que el anterior con correcciones. Funciona pero definitivamente no es bonito.
Honestamente, es mejor usar las respuestas anteriores.
fuente