LIMIT 10..20 в SQL Server
Я пытаюсь сделать что-то вроде:
SELECT * FROM table LIMIT 10,20
или
SELECT * FROM table LIMIT 10 OFFSET 10
но используя SQL Server
Единственное решение, которое я нашел, выглядит как overkill:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases
) a WHERE row > 5 and row <= 10
Я также нашел:
SELECT TOP 10 * FROM stuff;
... но это не то, что я хочу сделать, поскольку я не могу указать начальный предел.
Есть ли другой способ сделать это?
Кроме того, просто любопытно, есть ли причина, почему SQL Server не поддерживает функцию LIMIT
или что-то подобное? Я не хочу быть злым, но это действительно звучит как что-то, что требуется СУБД... Если это так, то мне жаль, что я так невежественен! Я работаю с MySQL и SQL + в течение последних 5 лет, поэтому...
Ответы
Ответ 1
Предложение LIMIT
не является частью стандартного SQL. Он поддерживается как расширение поставщика для SQL MySQL, PostgreSQL и SQLite.
Другие бренды базы данных могут иметь сходные функции (например, TOP
в Microsoft SQL Server), но они не всегда работают одинаково.
Трудно использовать TOP
в Microsoft SQL Server, чтобы имитировать предложение LIMIT
. Бывают случаи, когда он просто не работает.
Решение, которое вы показали, используя ROW_NUMBER()
, доступно в Microsoft SQL Server 2005 и более поздних версиях. Это лучшее решение (на данный момент), которое работает исключительно как часть запроса.
Другим решением является использование TOP
для извлечения первых строк count + offset, а затем использование API для поиска первых строк смещения.
См. также:
Ответ 2
Для SQL Server 2012 + вы можете использовать.
SELECT *
FROM sys.databases
ORDER BY name
OFFSET 5 ROWS
FETCH NEXT 5 ROWS ONLY
Ответ 3
как вы нашли, это предпочтительный метод sql-сервера:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases
) a WHERE a.row > 5 and a.row <= 10
Ответ 4
Если вы используете голосование SQL Server 2012+ за ответ Мартина Смита и используйте расширения OFFSET
и FETCH NEXT
для ORDER BY
,
Если вам так жаль, что вы застряли с более ранней версией, вы можете сделать что-то вроде этого,
WITH Rows AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
, *
FROM
[dbo].[SomeTable]
)
SELECT TOP 10
*
FROM
Rows
WHERE Row > 10
Я считаю, что функционально эквивалентно
SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn
и наилучшим образом я знаю, как это сделать в TSQL, до MS SQL 2012.
Если очень много строк, вы можете получить более высокую производительность, используя временную таблицу вместо CTE.
Ответ 5
К сожалению, ROW_NUMBER()
- лучшее, что вы можете сделать. Это на самом деле более правильно, потому что результаты предложения limit
или top
самом деле не имеют смысла без учета определенного порядка. Но это все еще боль, чтобы сделать.
Обновление: Sql Server 2012 добавляет функцию limit
-like через ключевые слова OFFSET и FETCH. Это анси-стандартный подход, в отличие от LIMIT
, который является нестандартным расширением MySql.
Ответ 6
Как насчет этого?
SET ROWCOUNT 10
SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC
Он дает вам последние 10 строк первых 20 строк. Один из недостатков заключается в том, что порядок обратный, но, по крайней мере, его легко запомнить.
Ответ 7
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)
Должны указывать записи 11-20.
Вероятно, он не слишком эффективен, если увеличивается, чтобы получить дальнейшие страницы, и не уверен, как это может повлиять на упорядочение.
Может потребоваться указать это в обоих операторах WHERE.
Ответ 8
Хорошим способом является создание процедуры:
create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases
) a WHERE a.row > @startfrom and a.row <= @endto
точно так же, как предел 0,2
///////////////
выполнить разбивку на страницы 0,4
Ответ 9
Только для решения для записей, которое работает в большинстве движков баз данных, но может быть не самым эффективным:
Select Top (ReturnCount) *
From (
Select Top (SkipCount + ReturnCount) *
From SourceTable
Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition
Замечание Pelase: последняя страница будет содержать строки ReturnCount независимо от того, что такое SkipCount. Но во многих случаях это может быть хорошо.
Ответ 10
Эквивалент 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
Ответ 11
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15
Будет печатать строки от 10 до 15.
Ответ 12
Пока этот формат работает для меня (но не лучшая производительность):
SELECT TOP {desired amount of rows} *
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}
Заметка сбоку, разбираясь на динамические данные, может привести к неожиданным/неожиданным результатам.
Ответ 13
Из онлайн-документации MS SQL Server (http://technet.microsoft.com/en-us/library/ms186734.aspx
), вот их пример, который я тестировал и работает, для получения определенного набора строк. ROW_NUMBER требует OVER, но вы можете заказать все, что вам нравится:
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
Ответ 14
Использовать весь SQL-сервер:
; с tbl as (SELECT ROW_NUMBER() over (упорядочить по (выберите 1)) как RowIndex, * из таблицы)
выберите топ 10 * из tbl, где RowIndex >= 10
Ответ 15
SELECT * FROM users WHERE Id Between 15 and 25
он будет печатать от 15 до 25 как ограничение в MYSQl