Oracle SELECT TOP 10 record

Ho un grosso problema con una dichiarazione SQL in Oracle. Voglio selezionare i 10 record TOP ordinati da STORAGE_DB che non sono in una lista da un’altra istruzione select.

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 aggiungo

 AND ROWNUM <= 10 ORDER BY STORAGE_GB DESC 

Sto ottenendo una specie di Records “random”. Penso che il limite si verifichi prima dell’ordine.

Qualcuno ha una buona soluzione? L’altro problema: questa query è molto lenta (10k + record)

    Dovrai inserire la query corrente nella sottoquery 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 

    Oracle applica rownum al risultato dopo che è stato restituito.
    È necessario filtrare il risultato dopo che è stato restituito, quindi è necessaria una sottoquery. Puoi anche utilizzare la funzione RANK () per ottenere risultati Top-N.

    Per le prestazioni prova a utilizzare NOT EXISTS al posto di NOT IN . Vedi questo per altro.

    Per quanto riguarda le prestazioni scadenti ci sono un certo numero di cose che potrebbe essere, e in realtà dovrebbe essere una domanda a parte. 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 date e se ha un indice, questa riscrittura avrà un rendimento migliore:

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

    Questo perché una conversione del tipo di dati disabilita l’uso di un indice B-Tree.

    Se si utilizza Oracle 12c, utilizzare:

    FETCH NEXT N ROWS SOLO

     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 

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

    Ottieni un set apparentemente casuale perché ROWNUM viene applicato prima di ORDER BY. Quindi la tua query prende le prime dieci righe e le ordina.0 Per selezionare i primi dieci stipendi dovresti usare una funzione analitica in una sottoquery, quindi filtrare quello:

      select * from (select empno, ename, sal, row_number() over(order by sal desc nulls last) rnm from emp) where rnm<=10 

    prova SELECT * FROM utenti SOLO FETCH NEXT 10 ROWS;

    Puoi semplicemente usare TOP Clause

    SELEZIONA TOP 10 * DA TABELLA;

    O

    SELECT nome_colonna FROM nome_tabella WHERE ROWNUM <= numero;