Sto usando Oracle 10g e il seguente paradigma per ottenere una pagina di 15 risultati come una volta (in modo che quando l'utente sta visualizzando la pagina 2 di un risultato di ricerca, vedono i record 16-30).(Oracle) Come ottenere il numero totale di risultati quando si utilizza una query di impaginazione?
select *
from
(select rownum rnum, a.*
from (my_query) a
where rownum <= 30)
where rnum > 15;
In questo momento mi sto dover eseguire un'istruzione SQL separato per fare un "select count" on "my_query" al fine di ottenere il numero totale di risultati per my_query (in modo che io possa mostrare al utente e utilizzarlo per calcolare il numero totale di pagine, ecc.).
C'è un modo per ottenere il numero totale di risultati senza farlo tramite una seconda query, cioè ottenendo da sopra query? Ho provato ad aggiungere "max (rownum)", ma non sembra funzionare (ottengo un errore [ORA-01747] che sembra indicare che non mi piace avere la parola chiave rownum nel gruppo di).
Il mio razionale per volere ottenere questo dalla query originale piuttosto che farlo in un'istruzione SQL separata è che "my_query" è una query costosa quindi preferisco non eseguirlo due volte (una volta per ottenere il conteggio, e una volta per ottenere la pagina di dati) se non devo; ma qualunque sia la soluzione che riesco a ottenere per ottenere il numero di risultati da una singola query (e allo stesso tempo ottenere la pagina di dati che mi serve) non dovrebbe aggiungere molto, se possibile, a un eventuale overhead aggiuntivo. Si prega di avvisare.
Ecco esattamente ciò che sto cercando di fare per il quale ricevo un errore ORA-01747 perché ritengo che non mi piaccia avere ROWNUM nel gruppo. Nota, se c'è un'altra soluzione che non usa max (ROWNUM), ma qualcos'altro, va benissimo anche lui. Questa soluzione è stata la mia prima riflessione su cosa potrebbe funzionare.
SELECT * FROM (SELECT r.*, ROWNUM RNUM, max(ROWNUM)
FROM (SELECT t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t0.LAST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND
t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30 GROUP BY r.*, ROWNUM) WHERE RNUM > 15
--------- -------- EDIT nota, in base al primo commento che ho provato la seguente che sembra funzionare. Non so però come si comporta bene rispetto ad altre soluzioni (sto cercando la soluzione che soddisfa il mio requisito ma che offre il meglio). Ad esempio, quando lo eseguo ci vogliono 16 secondi. Quando prendo il COUNT (*) OVER() RESULT_COUNT ci vogliono appena 7 secondi:
SELECT * FROM (SELECT r.*, ROWNUM RNUM,)
FROM (SELECT COUNT(*) OVER() RESULT_COUNT,
t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30) WHERE RNUM > 1
La spiegare i cambiamenti del piano di fare una sorta (ORDER BY TASTO STOP) per fare una finestra (SORT).
Prima:
SELECT STATEMENT()
COUNT (STOPKEY)
VIEW()
SORT (ORDER BY STOPKEY)
NESTED LOOPS()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC
Dopo:
SELECT STATEMENT()
COUNT (STOPKEY)
VIEW()
WINDOW (SORT)
NESTED LOOPS()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC
L'altro giorno, ho visto qualcuno usare 'selezionare a. *, Contare (*) su() da un ...' per ottenere il conteggio totale in ogni riga.Trucco accurato, ma non so esattamente come applicarlo qui :( – FrustratedWithFormsDesigner
Non sono sicuro di come funzioni questa query, ma se è qualcosa di relativamente statico, potresti ottenere il conteggio una volta e metterlo in una cache in una variabile applicativa, e poi ri-contare solo quando cambia la query? Non so se c'è un modo per ottenere il conteggio di un set di risultati senza effettivamente contare tutti i record. – FrustratedWithFormsDesigner
Cosa fai quando hai più suggerimenti che funzionerebbero allo stesso modo di beh? Quale dovresti contrassegnare in overflow come risposta? – BestPractices