В 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()