У 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
є 200k записів, вона спочатку отримає все, а потім застосувати ліміт? Цей запит ефективний?
Ця функція тепер стала спрощеною в 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
Для мене використання 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» , але його не стандарт , то нормально.
Додаючи незначні зміни до рішення 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
@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 ви можете досягти цього різними способами. Для даного реального прикладу ми взяли тут таблицю клієнтів.
Приклад 1: "Встановити 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 і 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", але при цьому "ЗАМОВИТИ ЗА" обов'язково
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}
Поясніть: