Sie haben nicht gesagt, ob Sie "X" und "Y" bei jeder Paginierung anpassen möchten. Wenn Sie dies nicht tun, ist der Ansatz wahrscheinlich nur gültig, wenn Sie ein hohes Vertrauen haben, dass die Daten ziemlich statisch sind.
Betrachten Sie das folgende Beispiel:
Meine Tabelle T hat 100 Zeilen Datumszeitstempel für "heute", mit ID =1 bis 100, und ich möchte die letzten 20 Zeilen für meine erste Seite. Also mache ich das:
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Ich führe meine Abfrage aus und erhalte ID =100 auf 80. So weit so gut - es ist alles auf der Seite des Benutzers, und sie brauchen 30 Sekunden, um die Daten zu lesen. Während dieser Zeit wurden der Tabelle weitere 17 Datensätze hinzugefügt (ID=101 bis 117).
Jetzt drückt der Benutzer "Nächste Seite"
Jetzt führe ich die Abfrage erneut aus, um den nächsten Satz zu erhalten
select *
from T
where date_col = trunc(sysdate)
order by id desc
offset 20 fetch next 20 rows only
Sie werden die Zeilen 80 bis 60 nicht sehen, was ihre Erwartung wäre, da sich die Daten geändert haben. Sie würden
a) Holen Sie Zeilen ID=117 bis 97 herunter und überspringen Sie sie aufgrund des OFFSETb) Holen Sie dann Zeilen ID=97 bis 77 herunter, um auf dem Bildschirm angezeigt zu werden
Sie werden verwirrt sein, weil sie so ziemlich die gleichen Zeilen sehen wie auf der ersten Seite.
Für die Paginierung gegen sich ändernde Daten möchten Sie sich im Allgemeinen von der Offset-Klausel fernhalten und Ihre Anwendung verwenden, um zu notieren, wo Sie hingekommen sind, dh
Seite 1
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Ich hole ID=100 herunter auf 80 ... Ich nehme zur Kenntnis der 80. Meine nächste Abfrage lautet dann
select *
from T
where date_col = trunc(sysdate)
AND ID<80
order by id desc
fetch first 20 rows only
und meine nächste Abfrage wäre
select *
from T
where date_col = trunc(sysdate)
AND ID<60
order by id desc
fetch first 20 rows only
und so weiter.