У 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}
Поясніть: