Ich verwende Oracle 10g und das folgende Paradigma, um eine Seite mit 15 Ergebnissen als Zeit zu erhalten (so dass der Benutzer, wenn er sich Seite 2 eines Suchergebnisses ansieht, die Datensätze 16-30 sieht).
select *
from
( select rownum rnum, a.*
from (my_query) a
where rownum <= 30 )
where rnum > 15;
Im Moment muss ich eine separate SQL-Anweisung ausführen, um eine "select count" auf "my_query" auszuführen, um die Gesamtzahl der Ergebnisse für my_query zu erhalten (so dass ich sie dem Benutzer anzeigen und verwenden kann, um die Gesamtzahl der Seiten usw. zu ermitteln).
Gibt es eine Möglichkeit, die Gesamtzahl der Ergebnisse zu erhalten, ohne dies über eine zweite Abfrage zu tun, d. h. indem man sie aus der obigen Abfrage erhält? Ich habe versucht, "max(rownum)" hinzuzufügen, aber das scheint nicht zu funktionieren (ich erhalte eine Fehlermeldung [ORA-01747], die darauf hinzuweisen scheint, dass das Schlüsselwort "rownum" in der Gruppe "by" nicht akzeptiert wird).
Mein Grundgedanke für wollen diese aus der ursprünglichen Abfrage zu erhalten, anstatt es in einer separaten SQL-Anweisung zu tun ist, dass "my_query" eine teure Abfrage ist, so dass ich lieber nicht es zweimal ausführen (einmal, um die Anzahl zu erhalten, und einmal, um die Seite der Daten zu erhalten), wenn ich nicht haben; aber was auch immer Lösung, die ich mit kommen kann, um die Anzahl der Ergebnisse aus innerhalb einer einzigen Abfrage zu erhalten (und zur gleichen Zeit erhalten die Seite der Daten, die ich brauche) sollte nicht viel, wenn überhaupt zusätzlichen Overhead, wenn möglich hinzufügen. Bitte beraten Sie.
Hier ist genau das, was ich versuche zu tun, wofür ich einen ORA-01747-Fehler erhalte, weil ich glaube, dass es mich nicht mag, wenn ich ROWNUM in der Gruppe von habe. Hinweis: Wenn es eine andere Lösung gibt, bei der nicht max(ROWNUM), sondern etwas anderes verwendet wird, ist das auch völlig in Ordnung. Diese Lösung war mein erster Gedanke, was funktionieren könnte.
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 -------- Hinweis: Auf der Grundlage des ersten Kommentars habe ich das Folgende ausprobiert, das zu funktionieren scheint. Ich weiß allerdings nicht, wie gut es im Vergleich zu anderen Lösungen funktioniert (ich suche nach der Lösung, die meine Anforderungen erfüllt, aber am besten funktioniert). Wenn ich dies zum Beispiel ausführe, dauert es 16 Sekunden. Wenn ich die COUNT(*) OVER () RESULT_COUNT herausnehme, dauert es nur 7 Sekunden:
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
Der Plan explain ändert sich von einem SORT (ORDER BY STOP KEY) zu einem WINDOW (SORT).
Vorher:
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
Danach:
SELECT STATEMENT ()
COUNT (STOPKEY)
VIEW ()
WINDOW (SORT)
NESTED LOOPS ()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC