Nie powiedziałeś, czy planujesz dostosowywać „X” i „Y” za każdym razem, gdy robisz paginację. Jeśli tego nie zrobisz, podejście jest prawdopodobnie prawidłowe tylko wtedy, gdy masz dużą pewność, że dane są dość statyczne.
Rozważ następujący przykład:
Moja tabela T ma sygnaturę czasową 100 wierszy dla „dzisiaj”, z identyfikatorami od 1 do 100, a chcę, aby ostatnie 20 wierszy było na mojej pierwszej stronie. Więc robię to:
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Uruchamiam moje zapytanie i otrzymuję ID=100 do 80. Jak dotąd dobrze - wszystko jest na stronie użytkownika, a odczytanie danych zajmuje 30 sekund. W tym czasie do tabeli dodano kolejnych 17 rekordów (ID=101 do 117).
Teraz użytkownik naciska „Następna strona”
Teraz ponownie uruchamiam zapytanie, aby uzyskać następny zestaw
select *
from T
where date_col = trunc(sysdate)
order by id desc
offset 20 fetch next 20 rows only
Nie zobaczą wierszy od 80 do 60, co byłoby ich oczekiwaniem, ponieważ dane się zmieniły. Zrobiliby
a) uzyskaj wiersze od ID=117 do 97 i pomiń je ze względu na PRZESUNIĘCIEb) następnie uzyskaj wiersze od ID=97 do 77, aby były wyświetlane na ekranie
Będą zdezorientowani, ponieważ widzą prawie ten sam zestaw wierszy, co na pierwszej stronie.
W przypadku stronicowania w odniesieniu do zmieniających się danych, zazwyczaj chcesz trzymać się z dala od klauzuli offset i użyć swojej aplikacji, aby zanotować, dokąd dotarłeś, tj.
Strona 1
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Pobieram ID=100 do 80... notuję z 80. Moje następne zapytanie będzie wtedy
select *
from T
where date_col = trunc(sysdate)
AND ID<80
order by id desc
fetch first 20 rows only
a moje następne zapytanie to
select *
from T
where date_col = trunc(sysdate)
AND ID<60
order by id desc
fetch first 20 rows only
i tak dalej.