SQL Server wybierz Ostatnie n wierszy

To znane pytanie, ale najlepsze rozwiązanie, jakie znalazłem, to coś w stylu:

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

Mam tabelę z mnóstwem wierszy. Nie ma możliwości korzystania z tego zapytania, ponieważ zajmuje to dużo czasu. Jak więc mogę wybrać Ostatnie n wierszy bez użycia ORDER BY?

EDIT

Sorry duplicated question of this one

Author: Community, 2010-11-16

15 answers

Możesz to zrobić również za pomocą funkcji numer wiersza według partycji. Świetny przykład można znaleźć tutaj :

Używam tabeli rozkazów bazy danych Northwind... Teraz pobierzmy ostatnie 5 zamówień złożonych przez pracownika 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
 33
Author: JonVD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 15:05:06

Możesz sprawić, że SQL server wybierze Ostatnie n wierszy używając tego SQL:

select * from tbl_name order by id desc limit N;
 74
Author: Niru Mukund Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-23 18:31:50

Przetestowałem Kod JonVD, ale okazało się, że był bardzo powolny, 6s.

Ten kod zajął 0s.

SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate    
FROM Orders where EmployeeID=5    
Order By OrderDate DESC
 40
Author: ABI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-23 18:34:47

Jeśli chcesz wybrać ostatnie liczby wierszy z tabeli.

Składnia będzie jak

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

Te stwierdzenia działają, ale w inny sposób. dziękuję.

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

W ten sposób możesz uzyskać ostatnie 10 wierszy, ale kolejność pokaże sposób descndingu

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)
 13
Author: Prafulla Sutradhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-25 05:52:59

Czy" Id " jest indeksowane? Jeśli nie, to jest to ważna rzecz do zrobienia (podejrzewam, że jest już zindeksowana).

Również, czy trzeba zwracać wszystkie kolumny? Możesz być w stanie uzyskać znaczną poprawę szybkości, jeśli potrzebujesz tylko mniejszego podzbioru kolumn, który może być w pełni zaspokajany przez indeks w kolumnie ID - np. jeśli masz NIEZAKLUSTROWANY indeks w kolumnie Id, bez innych pól zawartych w indeksie, to będzie musiał wykonać wyszukiwanie na indeksie klastrowym, aby faktycznie uzyskać reszta kolumn do powrotu i to może stanowić dużo kosztów zapytania. Jeśli jest to indeks klastrowy lub indeks NIEZAKLUSTROWANY, który zawiera wszystkie inne pola, które chcesz zwrócić w zapytaniu, to powinno być dobrze.

 6
Author: AdaTheDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-16 11:51:48

Najpierw najczęściej otrzymujesz liczbę rekordów z

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

A następnie:

W SQL Server 2012

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@TableRowsCount-@N> ROWS
FETCH NEXT @N ROWS ONLY;

W 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 > @TableRowsCount-@N 
 5
Author: Ardalan Shahgholi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-01 08:35:01

W bardzo ogólny sposób i do obsługi SQL server tutaj jest

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

I jak na wydajność, nie jest źle (mniej niż jedna sekunda dla ponad 10 000 rekordów na maszynie serwerowej)

 5
Author: Hakam Fostok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 13:58:24

Oto coś, czego możesz spróbować Bez order by, ale myślę, że wymaga to, aby każdy wiersz był wyjątkowy. N to żądana liczba wierszy, {[3] } to liczba wierszy w tabeli.

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

Jak wspomniano wcześniej, które wiersze są zwracane jest niezdefiniowane.

EDIT: to jest naprawdę dog slow. Nie ma żadnej wartości.

 4
Author: Dzamo Norton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-17 08:00:32
select * from (select top 6 * from vwTable order by Hours desc) T order by Hours
 4
Author: fth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 15:06:37

To zapytanie zwraca Ostatnie n wierszy w prawidłowej kolejności, ale jego wydajność jest słaba

select *
from (
    select top N *
    from TableName t
    order by t.[Id] desc
) as temp
order by temp.[Id]
 2
Author: timberhill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-04 09:19:34

Może to nie pasuje do pytania, ale ... ]}

Klauzula offsetowa

The OFFSET number klauzula umożliwia pominięcie liczby wierszy, a następnie zwrócenie wierszy.

Ten link doc jest do Postgres; Nie wiem czy dotyczy to Sybase/MS SQL Server.

 2
Author: Basil Bourque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 23:41:32
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
 0
Author: Slava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-19 11:34:56

Technika, której używam do odpytywania ostatnich wierszy w bardzo dużych tabelach (100+ milion lub 1 + miliard wierszy) ogranicza zapytanie do "odczytu" tylko najnowszego " N " procentu ostatnich wierszy. Jest to aplikacja w świecie rzeczywistym, na przykład robię to dla niehistorycznych ostatnich danych pogodowych lub ostatnich wyszukiwań kanałów informacyjnych lub ostatnich danych lokalizacji GPS.

Jest to ogromna poprawa wydajności jeśli wiesz na pewno, że Twoje rzędy są w najnowsze TOP 5% tabeli na przykład. Takie, że nawet jeśli istnieją indeksy na tabelach, to dodatkowo ogranicza możliwości tylko do 5% wierszy w tabelach, które mają 100+ milionów lub 1 + miliardów wierszy. Dzieje się tak zwłaszcza wtedy, gdy starsze dane wymagają odczytu dysku fizycznego, a nie tylko odczytu logicznego w pamięci.

Jest to znacznie bardziej wydajne niż SELECT TOP / procent / LIMIT, ponieważ nie wybiera wierszy, a jedynie ogranicza część danych, które mają być / align = "left" /

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'
 0
Author: CodeCowboyOrg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-07 04:12:35

Aby wyświetlić ostatnie 3 wiersze bez użycia 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) 
 -1
Author: abhinay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 15:31:37

Spróbuj użyć składni EXCEPT.
Coś takiego:

   SELECT * 
    FROM   clientDetails 
    EXCEPT 
    (SELECT TOP (numbers of rows - how many rows you want) * 
     FROM   clientDetails) 
 -1
Author: mayur godhani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-31 11:28:53