SQL Server SELECT LAST N Rows

Questa è una domanda conosciuta ma la soluzione migliore che ho trovato è qualcosa del tipo:

SELECT TOP N * FROM MyTable ORDER BY Id DESC 

Ho un tavolo con un sacco di file. Non è una possibilità di usare quella query perché richiede molto tempo. Quindi, come posso fare per selezionare le ultime N righe senza usare ORDER BY?

MODIFICARE

Scusa la domanda duplicata di questo

Puoi farlo usando anche la funzione ROW NUMBER BY PARTITION. Un grande esempio può essere trovato qui :

Sto usando la tabella Ordini del database Northwind … Ora recuperiamo gli ultimi 5 ordini effettuati da 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 

Puoi fare in modo che il server SQL selezioni le ultime N righe usando questo SQL:

 select * from tbl_name order by id desc limit N; 

Ho provato il codice di JonVD, ma ho scoperto che era molto lento, 6s.

Questo codice ha preso 0 s.

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

Se si desidera selezionare l’ultimo numero di righe da una tabella.

La syntax sarà come

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

Queste affermazioni funzionano ma in modi differrenti. grazie ragazzi.

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

in questo modo è ansible ottenere le ultime 10 righe, ma l’ordine mostrerà in modo descnding

 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) 

“Id” è indicizzato? In caso contrario, è una cosa importante da fare (ho il sospetto che sia già indicizzato).

Inoltre, devi restituire TUTTE le colonne? Potresti ottenere un sostanziale miglioramento della velocità se solo hai effettivamente bisogno di un sottoinsieme più piccolo di colonne che può essere COMPLETAMENTE soddisfatto dall’indice sulla colonna ID, ad esempio se hai un indice NONCLUSTERED sulla colonna Id, senza altri campi inclusi nell’indice, quindi dovrebbe fare una ricerca sull’indice cluster per ottenere effettivamente il resto delle colonne da restituire e ciò potrebbe comportare un sacco del costo della query. Se si tratta di un indice CLUSTERED o di un indice NONCLUSTERED che include tutti gli altri campi che si desidera restituire nella query, si dovrebbe andare bene.

Per prima cosa ottieni il conteggio dei record

  Declare @TableRowsCount Int select @TableRowsCount= COUNT(*) from  

E poi :

In SQL Server 2012

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

In SQL Server 2008

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

Ecco qualcosa che puoi provare senza un order by ma penso che sia necessario che ogni riga sia unica. N è il numero di righe che vuoi, L è il numero di righe nella tabella.

 select * from tbl_name except select top LN * from tbl_name 

Come notato in precedenza, quali righe vengono restituite non è definita.

EDIT: questo è in realtà cane lento. Di nessun valore in realtà.

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

In un modo molto generale e per supportare il server SQL ecco

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

e per le prestazioni, non è male (meno di un secondo per più di 10.000 record sul computer server)

Questa query restituisce le ultime N righe nell’ordine corretto, ma le prestazioni sono scadenti

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

Questo potrebbe non essere esattamente adatto alla domanda, ma …

Clausola OFFSET

La clausola del OFFSET number consente di saltare un numero di righe e successivamente di restituire le righe.

Quel collegamento doc è Postgres; Non so se questo si applica a Sybase / MS SQL Server.

 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 

Una tecnica che uso per interrogare le righe più recenti in tabelle molto grandi (100+ milioni o 1+ miliardi di righe) limita la query per “leggere” solo la percentuale “N” più recente di RECENT ROWS. Si tratta di applicazioni del mondo reale, ad esempio lo faccio per dati meteorologici recenti non storici o ricerche recenti sui feed di notizie o dati recenti relativi ai dati di localizzazione GPS.

Si tratta di un enorme miglioramento delle prestazioni se si sa con certezza che le righe si trovano nell’ultimo 5% TOP della tabella, ad esempio. Tale che anche se ci sono indici sulle tabelle, limita ulteriormente le possibilità a solo il 5% delle righe in tabelle che hanno 100+ milioni o 1+ miliardi di righe. Questo è specialmente il caso in cui i dati più vecchi richiedono letture di dischi fisici e non solo letture della memoria logica .

Questo è molto più efficiente di SELECT TOP | PERCENT | LIMIT perché non seleziona le righe, ma limita semplicemente la parte dei dati da cercare.

 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' 

Per visualizzare le ultime 3 righe senza utilizzare l’ 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) 

Prova a utilizzare la syntax EXCEPT .
Qualcosa come questo:

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