Pregunta

Tengo un gran problema con una sentencia de SQL en Oracle. Quiero seleccionar entre los 10 primeros registros clasificadas por STORAGE_DB que no están en una lista de una otra instrucción de selección.

Éste bien funciona 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 añadiendo

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

Me estoy poniendo algún tipo de registros "al azar". Creo que es porque el límite toma en su lugar antes de la orden.

¿Alguien tiene una buena solución? El otro problema: Esta consulta es realmente lenta (10K + registros)

¿Fue útil?

Solución

Usted tendrá que poner su consulta actual en la subconsulta de la siguiente manera:

SELECT * FROM (
  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')
  ORDER BY STORAGE_GB DESC )
WHERE ROWNUM <= 10

rownum al resultado después de que haya sido devuelto. lo que necesita para filtrar el resultado después de que haya sido devuelto, por lo que se requiere una subconsulta. También puede utilizar RANK () la función para obtener Top-N resultados.
Para obtener un rendimiento trate de usar NOT EXISTS en lugar de NOT IN. Ver este por más.

Otros consejos

Si está utilizando Oracle 12c, utilice:

  

FETCH SIGUIENTE N sólo las filas

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')
  ORDER BY STORAGE_GB DESC
FETCH NEXT 10 ROWS ONLY

Más información: http://docs.oracle.com/javadb /10.5.3.0/ref/rrefsqljoffsetfetch.html

En cuanto a los malos resultados hay cualquier cantidad de cosas que podría ser, y lo que realmente debería ser una cuestión aparte. Sin embargo, hay una cosa obvia que podría ser un problema:

WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

Si HISTORY_DATE realmente es una columna de fecha y si tiene un índice entonces esta reescritura se obtienen mejores resultados:

WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')  

Esto se debe a una conversión de tipo de datos deshabilita el uso de un índice B-Tree.

try

SELECT * FROM users FETCH NEXT 10 ROWS ONLY;

Se obtiene un conjunto aparentemente aleatoria porque ROWNUM se aplica antes de que el ORDER BY. Por lo que su consulta toma las primeras filas y diez tipos them.0 para seleccionar los diez mejores salarios que debe utilizar una función analítica en una subconsulta, entonces filtro que:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top