В 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 параметр следует использовать одну индексирование для этого , а не нормальной индексации с нуля.
WHERE RowNum >= (@Offset + 1)
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified, MSSQL2008 R2.
Tableесть 200 тыс. Записей, сначала он получит все, а затем установит лимит? Этот запрос эффективен?
Эта функция теперь упрощена в 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: необходимое количество следующих строкSQL_CALC_FOUND_ROWSпри использовании этого?
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()было реализовано.
AS xx
Вы можете использовать ROW_NUMBER в выражении Common Table для достижения этой цели.
;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 для меня не сработало.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows, вы должны преобразовать его как SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1. Я отредактирую свой ответ. Спасибо и извините за мой английский.
Другой образец:
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» , но его не стандарт , то нормально.
Добавляя небольшую вариацию решения Аарона, я обычно параметризую номер страницы (@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
-- @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
@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есть ли явно, если это то, что нужноСпециально для SQL-SERVER вы можете достичь этого разными способами. Для данного реального примера мы взяли таблицу Customer здесь.
Пример 1: с помощью «SET ROWCOUNT»
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Чтобы вернуть все строки, установите ROWCOUNT в 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Пример 2: с "ROW_NUMBER and OVER"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Пример 3: с "OFFSET and FETCH", но с этим "ORDER BY" является обязательным
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Надеюсь, это поможет вам.
С тех пор, как я тестирую больше раз, этот скрипт более полезен на 1 миллион записей на каждой странице. 100 записей с разбивкой на страницы работают быстрее, мой компьютер выполняет этот скрипт за 0 секунд, в то время как сравнение с mysql имеет собственный предел и смещение около 4.5 секунд, чтобы получить результат.
Кто-то может не заметить, что Row_Number () всегда сортируется по определенному полю. В случае, если нам нужно определить только строку в последовательности, следует использовать:
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Объясните: