risposta-alla-domanda-sullo-sviluppo-web-bd.com

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 questa

111
Diego

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
33
JonVD

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;
75
Niru Mukund Shah

Ho testato il codice di JonVD, ma ho trovato che era molto lento, 6s.

Questo codice ha richiesto 0 secondi.

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

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

La sintassi 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 è possibile ottenere le ultime 10 righe, ma l'ordine mostrerà il modo descrittivo 

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

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

Inoltre, devi restituire TUTTE le colonne? Potresti essere in grado di 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 es. se si ha un indice NONCLUSTERED sulla colonna Id, senza altri campi inclusi nell'indice, allora si dovrebbe fare una ricerca sull'indice cluster per ottenere effettivamente il resto delle colonne da restituire e potrebbe essere molto 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.

6
AdaTheDev

In un modo molto generale e per supportare il server SQL qui è 

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)

6
Hakam Fostok

Per prima cosa ottieni il conteggio dei record 

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

E poi :

In SQL Server 2012

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
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  <Your_Table>
    Order By <your Field>
) AS TempTable
WHERE sequencenumber > @[email protected] 
5
select * from (select top 6 * from vwTable order by Hours desc) T order by Hours
4
fth

Ecco qualcosa che puoi provare senza 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 L-N * from tbl_name

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

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

4
Dzamo Norton

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]
2
timberhill

Questo potrebbe non essere esattamente adatto alla domanda, ma ...

Clausola OFFSET

La clausola OFFSET number consente di saltare un numero di righe e quindi restituire le righe dopo di ciò. 

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

2
Basil Bourque

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 più recente "N "percentuale di RECENT ROWS. Si tratta di applicazioni del mondo reale, ad esempio lo faccio per dati meteorologici recenti non storici, o recenti ricerche di feed di notizie o dati recenti di dati di posizione GPS.

Questo è un enorme miglioramento delle prestazioni se sai per certo che le tue 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 Disco fisico legge e non solo Logical In Memory legge.

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'
0
CodeCowboyOrg

usa desc con orderby alla fine della query per ottenere gli ultimi valori.

0
Sara
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
Slava