Не казахте дали планирате да коригирате "X" и "Y" всеки път, когато правите пагинацията. Ако не го направите, тогава подходът вероятно е валиден само ако имате голяма увереност, че данните са доста статични.
Разгледайте следния пример:
Моята таблица T има клеймо за дата и време от 100 реда за „днес“, съответно с ID=1 до 100 и искам последните 20 реда за първата си страница. Затова правя следното:
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Пускам заявката си и получавам ID=100 до 80. Дотук добре - всичко е на страницата на потребителя и им отнема 30 секунди минути, за да прочетат данните. През това време към таблицата са добавени още 17 записа (ID=101 до 117).
Сега потребителят натиска "Следваща страница"
Сега изпълнявам отново заявката, за да получа следващия набор
select *
from T
where date_col = trunc(sysdate)
order by id desc
offset 20 fetch next 20 rows only
Те няма да видят редове от 80 до 60, което би било тяхното очакване, тъй като данните са се променили. Те биха
a) намалете редовете ID=117 до 97 и ги пропуснете поради OFFSETb) след това намалете редовете ID=97 до 77, за да се показват на екрана
Те ще бъдат объркани, защото виждат почти същия набор от редове, както на първата страница.
За пагиниране срещу промяна на данни обикновено искате да стоите далеч от клаузата за отместване и да използвате приложението си, за да отбележите докъде сте стигнали, т.е.
Страница 1
select *
from T
where date_col = trunc(sysdate)
order by id desc
fetch first 20 rows only
Извличам ID=100 до 80... вземам си бележка от 80. След това следващото ми запитване ще бъде
select *
from T
where date_col = trunc(sysdate)
AND ID<80
order by id desc
fetch first 20 rows only
и следващото ми запитване ще бъде
select *
from T
where date_col = trunc(sysdate)
AND ID<60
order by id desc
fetch first 20 rows only
и така нататък.