В Oracle
:
SELECT *
FROM (
SELECT t.*, rownum AS rn
FROM tbl_messages t
ORDER BY
dt_made DESC, tnr_id DESC
)
WHERE rn > 40
AND rownum <= 20
В SQL Server 2005
и выше:
DECLARE @start INT
DECLARE @pagesize INT
SET @start = 40
SET @pagesize = 20
SELECT *
FROM (
SELECT TOP (@start + @pagesize)
t.*, ROW_NUMBER() OVER (ORDER BY dt_made DESC, tnr_id DESC) AS rn
FROM tbl_messages t
ORDER BY
dt_made DESC, tnr_id DESC
) q
WHERE rn > @start
ROW_NUMBER
поддерживается также Oracle
, но из-за деталей реализации немного менее эффективен, чем rownum
.
См. Эту статью в моем блоге для сравнения производительности:
Обновление:
Если вы можете допустить некоторые несоответствия, вызванные одновременными обновлениями, вы можете запомнить последнюю запись на текущей странице на стороне клиента и использовать ее для более быстрого получения следующих результатов:
SELECT TOP 20 *
FROM tbl_messages t
WHERE dt_made <= @last_dt_made
AND NOT (dt_made = @last_dt_made AND tnr_id >= @last_tnr_id)
ORDER BY
dt_made DESC, tnr_id DESC