Мне нужно прочитать содержимое таблицы базы данных MS SQL, используя разбиение на страницы, т.е. извлечение первой страницы из N строк, затем второй страницы из N строк и так далее.
Если содержимое базы данных значительно меняется во время разбивки на страницы, простой запрос на разбивку на страницы, например:
SELECT *
FROM (SELECT a.*,
ROW_NUMBER() OVER (ORDER BY id) AS rnum
FROM articles a)
WHERE rnum <= 10
AND rnum >= 6;
может работать не надежно. Вставленные строки могут быть пропущены или могут привести к повторению последующих строк, а удаленные строки могут привести к пропуску последующих строк.
Я мог бы избежать таких проблем, выполнив любое из следующих действий:
- Блокировка строк от обновления в течение всей разбивки на страницы — слишком строгие ограничения
- Скопируйте строки во временную таблицу перед пейджингом - слишком медленно
- Выбор по комбинации номера строки и отсортированного значения, которое отображалось в конце предыдущей страницы, возобновление в соответствующем месте на основе изменяющейся таблицы, но по-прежнему получение только следующих N строк
Мне нравится третье решение, но мне трудно его реализовать, когда в столбцах сортировки есть повторяющиеся значения.
Например, предположим, что у меня есть список статей, отсортированных по убыванию рейтинга. Если рейтинг одинаковый, они сортируются по возрастанию идентификатора (идентификаторы уникальны):
ID RATING
9 34
3 32
6 32
8 32
12 32
1 25
2 23
Теперь мне нужны страницы из 3 статей, что означает, что на первой странице будут статьи 9, 3 и 6. Это делается путем запроса трех лучших статей из отсортированного списка.
Теперь я хочу взять следующие 3 статьи, начиная со статьи 8, используя идентификатор статьи в качестве маркера, с которого можно продолжить.
Если бы я сказал базе данных взять репутацию статьи 8, а затем взять 3 статьи с репутацией ниже этой, я бы пропустил статью 12.
Если бы я сказал базе данных взять репутацию статьи 8, а затем взять 3 статьи, репутация которых ниже или равна этой, я бы повторил статьи 3 и 6.
Какой SQL-запрос (или комбинацию запросов) я могу использовать для возобновления разбиения на страницы из статьи 8, используя идентификатор статьи в качестве маркера для возобновления?