SQL Server SELECT LAST N Rows

Это известный вопрос, но лучшее, что я нашел, это что-то вроде:

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

У меня есть таблица с большим количеством строк. Невозможно использовать этот запрос, потому что требуется много времени. Итак, как я могу сделать, чтобы выбрать последние N строк без использования ORDER BY?

ИЗМЕНИТЬ

Извините, дублированный вопрос этого

Ответ 1

Вы можете сделать это, используя функцию ROW NUMBER BY PARTITION. Большой пример можно найти здесь:

Я использую таблицу Orders из базы данных Northwind... Теперь давайте вернем последние 5 заказов, размещенных Employee 5:

SELECT ORDERID, CUSTOMERID, OrderDate
FROM
(
    SELECT ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY OrderDate DESC) AS OrderedDate,*
    FROM Orders
) as ordlist

WHERE ordlist.EmployeeID = 5
AND ordlist.OrderedDate <= 5

Ответ 2

Вы можете заставить SQL-сервер выбрать последние N строк, используя этот SQL:

select * from tbl_name order by id desc limit N;

Ответ 3

Я тестировал код JonVD, но обнаружил, что он был очень медленным, 6 с.

Этот код занял 0 секунд.

SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate    
FROM Orders where EmployeeID=5    
Order By OrderDate DESC

Ответ 4

Если вы хотите выбрать последние числа строк из таблицы.

Синтаксис будет похож на

 select * from table_name except select top 
 (numbers of rows - how many rows you want)* from table_name

Эти инструкции работают, но отличаются друг от друга. спасибо вам, ребята.

 select * from Products except select top (77-10) * from Products

таким образом вы можете получить последние 10 строк, но порядок покажет путь отправки

select top 10 * from products
 order by productId desc 

 select * from products
 where productid in (select top 10 productID from products)
 order by productID desc

 select * from products where productID not in 
 (select top((select COUNT(*) from products ) -10 )productID from products)

Ответ 5

Идентифицирован ли идентификатор? Если нет, это важная вещь (я подозреваю, что она уже проиндексирована).

Кроме того, вам нужно вернуть ВСЕ столбцы? Возможно, вам удастся добиться существенного улучшения скорости, если на самом деле вам понадобится меньший поднабор столбцов, который может быть полностью удовлетворен индексом в столбце ID - например. если у вас есть индекс NONCLUSTERED в столбце Id, без каких-либо других полей, включенных в индекс, тогда он должен будет выполнить поиск по кластерному индексу, чтобы фактически вернуть остальные столбцы, и это может быть много от стоимости запроса. Если это индекс CLUSTERED или индекс NONCLUSTERED, который включает все остальные поля, которые вы хотите вернуть в запросе, тогда вы должны быть в порядке.

Ответ 6

select * from (select top 6 * from vwTable order by Hours desc) T order by Hours

Ответ 7

Сначала вы получите наибольшее количество записей из

 Declare @TableRowsCount Int
 select @TableRowsCount= COUNT(*) from <Your_Table>

И затем:

В SQL Server 2012

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@[email protected]> ROWS
FETCH NEXT @N ROWS ONLY;

В SQL Server 2008

SELECT *
FROM 
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS sequencenumber, *
FROM  <Your_Table>
    Order By <your Field>
) AS TempTable
WHERE sequencenumber > @[email protected] 

Ответ 8

Здесь вы можете попробовать без order by, но я думаю, что это требует, чтобы каждая строка была уникальной. N - количество строк, которое вы хотите, L - количество строк в таблице.

select * from tbl_name except select top L-N * from tbl_name

Как отмечалось ранее, какие строки возвращаются undefined.

EDIT: на самом деле это собака медленная. Не имеет значения.

Ответ 9

В очень общем виде и для поддержки SQL-сервера здесь

SELECT TOP(N) *
FROM tbl_name
ORDER BY tbl_id DESC

и для производительности это неплохо (менее одной секунды для более чем 10 000 записей на сервере)

Ответ 10

Это может быть не совсем правильно для вопроса, но...

Предложение OFFSET

Предложение OFFSET number позволяет пропустить несколько строк и после этого вернуть строки после этого.

Эта ссылка на doc для Postgres; Я не знаю, относится ли это к Sybase/MS SQL Server.

Ответ 11

Этот запрос возвращает последние N строк в правильном порядке, но производительность низкая

select *
from (
    select top N *
    from TableName t
    order by t.[Id] desc
) as temp
order by temp.[Id]

Ответ 12

DECLARE @MYVAR  NVARCHAR(100)
DECLARE @step  int
SET @step = 0;


DECLARE MYTESTCURSOR CURSOR
DYNAMIC 
FOR
SELECT col FROM [dbo].[table]
OPEN MYTESTCURSOR
FETCH LAST FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;


WHILE @step < 10
BEGIN   
    FETCH PRIOR FROM MYTESTCURSOR INTO @MYVAR
        print @MYVAR;
        SET @step = @step + 1;
END   
CLOSE MYTESTCURSOR
DEALLOCATE MYTESTCURSOR

Ответ 13

Метод, который я использую для запроса строк MOST RECENT в очень больших таблицах (100+ миллионов или 1 + миллиард строк) ограничивает запрос только "чтением" самый последний "N" процент от RECENT ROWS. Это приложения реального мира, например, я делаю это для неисторических последних данных о погоде или недавних поисков новостей или последних данных о местоположении данных GPS.

Это значительное улучшение производительности, если вы точно знаете, что ваши строки находятся в последних ТОП-5% таблицы, например. Таким образом, даже если в таблицах есть индексы, это ограничивает возможности только 5% строк в таблицах, которые содержат более 100 миллионов или 1 миллиард строк. Это особенно характерно для случаев, когда для старых данных требуется Физический диск, а не только Логическая память.

Это намного эффективнее, чем SELECT TOP | PERCENT | LIMIT, поскольку он не выбирает строки, а просто ограничивает часть данных для поиска.

DECLARE @RowIdTableA BIGINT
DECLARE @RowIdTableB BIGINT
DECLARE @TopPercent FLOAT

-- Given that there is an Sequential Identity Column
-- Limit query to only rows in the most recent TOP 5% of rows
SET @TopPercent = .05
SELECT @RowIdTableA = (MAX(TableAId) - (MAX(TableAId) * @TopPercent)) FROM TableA
SELECT @RowIdTableB = (MAX(TableBId) - (MAX(TableBId) * @TopPercent)) FROM TableB

SELECT *
FROM TableA a
INNER JOIN TableB b ON a.KeyId = b.KeyId
WHERE a.Id > @RowIdTableA AND b.Id > @RowIdTableB AND
      a.SomeOtherCriteria = 'Whatever'

Ответ 14

Чтобы отобразить последние 3 строки без использования order by:

select * from Lms_Books_Details where Book_Code not in 
 (select top((select COUNT(*) from Lms_Books_Details ) -3 ) book_code from Lms_Books_Details) 

Ответ 15

Попробуйте использовать синтаксис EXCEPT.
Что-то вроде этого:

   SELECT * 
    FROM   clientDetails 
    EXCEPT 
    (SELECT TOP (numbers of rows - how many rows you want) * 
     FROM   clientDetails)