Tengo un gran problema con una declaración SQL en Oracle. Quiero seleccionar los TOP 10 registros ordenados por STORAGE_DB que no están en una lista de otra declaración de selección.
Este funciona bien para todos los registros:
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID
FROM HISTORY
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
Pero cuando estoy agregando
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
Estoy obteniendo algún tipo de registros "al azar". Creo que porque el límite tiene lugar antes de la orden.
¿Alguien tiene una buena solución? El otro problema: esta consulta es realmente lenta (10k + registros)
Respuestas:
Deberá poner su consulta actual en la subconsulta de la siguiente manera:
Oracle aplica rownum al resultado después de que ha sido devuelto.
Debe filtrar el resultado después de que se haya devuelto, por lo que se requiere una subconsulta. También puede usar la función RANK () para obtener resultados Top-N.
Para el rendimiento, intente usar
NOT EXISTS
en lugar deNOT IN
. Mira esto para más.fuente
FETCH NEXT N ROWS ONLY
respuesta a continuación.Si está utilizando Oracle 12c, use:
Más información: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
fuente
Con respecto al bajo rendimiento, hay muchas cosas que podrían ser, y realmente debería ser una pregunta separada. Sin embargo, hay una cosa obvia que podría ser un problema:
Si HISTORY_DATE realmente es una columna de fecha y si tiene un índice, esta reescritura funcionará mejor:
Esto se debe a que una conversión de tipo de datos deshabilita el uso de un índice B-Tree.
fuente
tratar
fuente
Obtiene un conjunto aparentemente aleatorio porque ROWNUM se aplica antes de ORDER BY. Por lo tanto, su consulta toma las primeras diez filas y las ordena.0 Para seleccionar los diez salarios principales, debe usar una función analítica en una subconsulta y luego filtrar eso:
fuente