В PostgreSQL есть ключевые слова Limit
и Offset
, которые позволят очень легко разбивать страницы на результирующие множества.
Каков эквивалентный синтаксис для Sql Server?
В PostgreSQL есть ключевые слова Limit
и Offset
, которые позволят очень легко разбивать страницы на результирующие множества.
Каков эквивалентный синтаксис для Sql Server?
Эквивалент LIMIT
равен SET ROWCOUNT
, но если вам нужна общая разбивка на страницы, лучше написать такой запрос:
;WITH Results_CTE AS
(
SELECT
Col1, Col2, ...,
ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
FROM Table
WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
Преимущество здесь заключается в параметризации смещения и ограничения в случае, если вы решите изменить свои параметры поискового вызова (или разрешить пользователю делать это).
Примечание. параметр @Offset
должен использовать для этого индексирование на основе одного, а не стандартное индексирование с нулевым индексом.
Эта функция теперь стала проще в SQL Server 2012. Это работает с SQL Server 2012 и далее.
Предел со смещением для выбора от 11 до 20 строк в SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
OFFSET
: количество пропущенных строкNEXT
: необходимое количество следующих строкselect top {LIMIT HERE} * from (
select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n
from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
Примечание:
Это решение будет работать только в SQL Server 2005 или выше, поскольку это было тогда, когда был реализован ROW_NUMBER()
.
Вы можете использовать ROW_NUMBER в Common Table Expression, чтобы достичь этого.
;WITH My_CTE AS
(
SELECT
col1,
col2,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
SELECT
col1,
col2
FROM
My_CTE
WHERE
row_number BETWEEN @start_row AND @end_row
Для меня использование OFFSET и FETCH было медленным, поэтому я использовал комбинацию TOP и OFFSET, как это (что было быстрее):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Примечание. Если вы используете TOP и OFFSET вместе в том же запросе, что:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Затем вы получите сообщение об ошибке, поэтому для совместного использования TOP и OFFSET вам необходимо разделить его на дополнительный запрос.
И если вам нужно использовать SELECT DISTINCT, тогда запрос будет выглядеть так:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Примечание. Использование SELECT ROW_NUMBER с DISTINCT не помогло мне.
Еще один пример:
declare @limit int
declare @offset int
set @offset = 2;
set @limit = 20;
declare @count int
declare @idxini int
declare @idxfim int
select @idxfim = @offset * @limit
select @idxini = @idxfim - (@limit-1);
WITH paging AS
(
SELECT
ROW_NUMBER() OVER (order by object_id) AS rowid, *
FROM
sys.objects
)
select *
from
(select COUNT(1) as rowqtd from paging) qtd,
paging
where
rowid between @idxini and @idxfim
order by
rowid;
Существует здесь кто-то рассказывал об этой функции в sql 2011, ее грустно они выбирают немного другое ключевое слово "OFFSET/FETCH", но его нестандартный, тогда хорошо.
Добавив небольшое изменение в решение Aaronaught, я обычно параметризую номер страницы (@PageNum) и размер страницы (@PageSize). Таким образом, каждое событие щелчка страницы просто отправляет номер запрашиваемой страницы вместе с настраиваемым размером страницы:
begin
with My_CTE as
(
SELECT col1,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
select * from My_CTE
WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1)
AND @PageNum * @PageSize
end
Самое близкое, что я мог сделать, это
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Я думаю, что похоже на select * from [db].[dbo].[table] LIMIT 0, 10
select top (@TakeCount) * --FETCH NEXT
from(
Select ROW_NUMBER() OVER (order by StartDate) AS rowid,*
From YourTable
)A
where Rowid>@SkipCount --OFFSET
@nombre_row :nombre ligne par page
@page:numero de la page
//--------------code sql---------------
declare @page int,@nombre_row int;
set @page='2';
set @nombre_row=5;
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
FROM etudiant
) AS RowConstrainedResult
WHERE RowNum >= ((@page-1)*@nombre_row)+1
AND RowNum < ((@page)*@nombre_row)+1
ORDER BY RowNum
Так как никто еще не предоставил этот код:
SELECT TOP @limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
t1.id NOT IN
(SELECT TOP @offset id
FROM t1
WHERE c1 = v1, c2 > v2...
ORDER BY o1, o2...)
ORDER BY o1, o2...
Важные моменты:
@limit
можно заменить числом результатов для извлечения,@offset
- количество результатов для пропусковwhere
и order by
и будет предоставлять неверные результаты, если они не синхронизированыorder by
явно существует то, что нужно-- @RowsPerPage can be a fixed number and @PageNumber number can be passed
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2
SELECT *
FROM MemberEmployeeData
ORDER BY EmployeeNumber
OFFSET @PageNumber*@RowsPerPage ROWS
FETCH NEXT 10 ROWS ONLY
В SQL-сервере вы должны использовать TOP вместе с ROW_NUMBER()