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 для поиска первых строк смещения.

См. также:

Ответ 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