Domanda

Ho un grosso problema con un'istruzione SQL in Oracle. Voglio selezionare i 10 record in ordine di STORAGE_DB che non sono in un elenco da un'altra dichiarazione prescelta.

Questo funziona bene per tutti i record:

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') 

Ma quando sto aggiungendo

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

Sono ottenere un certo genere di "casuali" Records. Credo perché il limite avviene in vigore prima della fine.

Se qualcuno ha una buona soluzione? L'altro problema: Questa query è davvero lento (10k + record)

È stato utile?

Soluzione

Avrete bisogno di mettere la vostra query corrente in subquery come di seguito:

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 per il risultato dopo che è stato restituito.
è necessario filtrare il risultato dopo che è stato restituito, quindi è necessario un subquery. È inoltre possibile utilizzare RANK () funzione per ottenere Top-N risultati.
Per prestazioni provare a utilizzare NOT EXISTS al posto di NOT IN. Vedere questo per ulteriori informazioni.

Altri suggerimenti

Se si utilizza Oracle 12c, utilizzare:

  

FETCH AVANTI N solo le righe

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

Più informazioni: http://docs.oracle.com/javadb /10.5.3.0/ref/rrefsqljoffsetfetch.html

Per quanto riguarda lo scarso rendimento ci sono un certo numero di cose che potrebbe essere, e dovrebbe davvero essere una questione a sé stante. Tuttavia, c'è una cosa ovvia che potrebbe essere un problema:

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

Se HISTORY_DATE è davvero una colonna di data e se ha un indice quindi questa riscrittura avrà un rendimento migliore:

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

Questo perché una conversione tipo di dati disabilita l'utilizzo di un indice B-Tree.

try

SELECT * FROM users FETCH NEXT 10 ROWS ONLY;

Si ottiene un insieme apparentemente casuale perché ROWNUM viene applicato prima ORDER BY. Quindi la query prende le prime dieci righe e tipi them.0 Per selezionare i primi dieci stipendi si dovrebbe usare una funzione analitica in una sottoquery, poi filtrare che:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top