SQL Server SELECT ULTIME righe


139

Questa è una domanda nota ma la soluzione migliore che ho trovato è qualcosa di simile:

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

Ho una tabella con molte righe. Non è possibile utilizzare quella query perché richiede molto tempo. Quindi, come posso fare per selezionare le ultime N righe senza usare ORDER BY?

MODIFICARE

Siamo spiacenti domanda duplicata di questo


Cosa si intende per "ultima N"? Senza un ordine, "last N" non ha molto senso. Se intendi "ultima N da inserire", non puoi fare affidamento su SQL Server per dartelo - devi usare una clausola ORDER BY.
Daniel Renshaw,

@Daniel Renshaw: l'ultima N della tabella senza forzare SQL Server a ordinare tutta la tabella perché diventa molto lenta
Diego

La query nella tua domanda è il modo migliore. Se idè indicizzato, scansionerà quell'indice al contrario e si fermerà dopo le prime 5 righe. Se non è indicizzato, sarà necessario eseguire un TOP Nordinamento. Questo non sarà peggio di qualsiasi altro modo di farlo. Non ordina l'intero tavolo (anche se avrebbe bisogno di scansionare l'intero tavolo)
Martin Smith,

Risposte:


38

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

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

1
La funzione NUMERO DI FILA PER PARTIZIONE utilizza anche un ordinamento .. è necessario ordinare la tabella per assegnare i numeri di riga per ciascun record ...
Sadhir

Questo è vero, ma senza una sorta di natura che semplicemente non funzionerà, la soluzione migliore è indicizzare le colonne principali colpite ed eseguire con qualcosa come la query sopra.
JonVD,

101

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

select * from tbl_name order by id desc limit N;

2
Che ne dici di compatibilità versione?
Fractaliste,

63
Questo non funziona in SQL Server. Sembra una funzionalità MySQL, PostgreSQL e SQLite.
Tim Friesen,

3
Tutti i prodotti elencati sono sicuramente server SQL. Se vuoi parlare di MS SQL Server, perché non chiamarlo così?
gena2x,

4
sono confuso, la domanda chiede come creare una query di selezione "senza utilizzare ORDER BY" e la query di selezione nella risposta ha "ordina per". È una specie di "ordine per" senza "ordine per"?
Robert Sinclair,

5
@ gena2x questa domanda è taggata SQL Server. Quel tag si riferisce a Microsoft SQL Server.
Martin Smith,

51

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

Questo codice ha impiegato 0 secondi.

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

4
Quante file ?? Quando hai molte file che possono essere REALMENTE lente
Diego,

@Diego Perché? Se hai OrderDateindicizzato, dovrebbe essere sostanzialmente altrettanto veloce scegliere la prima o l'ultima N riga di una query. Mi rendo conto che esiste una possibilità OrderDateben correlata all'ordine inserito, ma questo è un effetto collaterale nella migliore delle ipotesi e richiede comunque una scansione della tabella, no? (E non credo che risponda a ciò che l'OP indica come un dupe meglio definito della loro domanda : cioè, senza smistamento)
ruffin

1
@Diego - Perché credi che questo sarà più lento della risposta che hai accettato?
Martin Smith,

2
Ciò restituisce le righe sottosopra. È quindi necessario riordinare da loro per ripristinare l'ordine originale.
Marco

15

Se si desidera selezionare gli ultimi numeri 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 modi diversi. 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à la via discendente

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)

7

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)


1
ben 10'000 dischi non sono nulla di cui dovresti preoccuparti delle prestazioni. Quando inizi a parlare di milioni di dischi di quelli che puoi iniziare a pensare all'esibizione
Dom84,

6

"Id" è indicizzato? Altrimenti, è una cosa importante da fare (sospetto che sia già indicizzato).

Inoltre, devi restituire TUTTE le colonne? Potresti essere in grado di ottenere un sostanziale miglioramento della velocità se in realtà hai bisogno solo di un sottoinsieme di colonne più piccolo che può essere COMPLETAMENTE soddisfatto dall'indice sulla colonna ID - ad esempio se hai un indice NONCLUSTER sulla colonna Id, senza altri campi inclusi nell'indice, quindi dovrebbe eseguire una ricerca sull'indice cluster per ottenere effettivamente il resto delle colonne da restituire e ciò potrebbe comportare un costo considerevole per la 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, allora si dovrebbe andare bene.


6

Per prima cosa ottieni il conteggio dei record da

 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 <@TableRowsCount-@N> 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 > @TableRowsCount-@N 

4

Ecco qualcosa che puoi provare senza, order byma penso che richieda che ogni riga sia unica. Nè il numero di righe che desideri, Lè il numero di righe nella tabella.

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

Come notato prima, quali righe vengono restituite non è definito.

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


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

2

Questa query restituisce le ultime N righe nell'ordine corretto, ma le prestazioni sono scarse

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

2

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


1

Questo potrebbe non essere del tutto adatto alla domanda, ma ...

Clausola OFFSET

La OFFSET numberclausola consente di saltare un numero di righe e quindi restituire le righe successive.

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


1
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

1

MS non supporta LIMIT in t-sql. Il più delle volte ottengo solo MAX (ID) e quindi sottraggo.

select * from ORDERS where ID >(select MAX(ID)-10 from ORDERS)

Ciò restituirà meno di 10 record quando l'ID non è sequenziale.


0

Una tecnica che uso per interrogare le righe PIÙ RECENTI in tabelle molto grandi (100+ milioni o 1+ miliardi di righe) sta limitando la query alla "lettura" solo della più recente percentuale "N" di RECENT ROWS. Si tratta di applicazioni del mondo reale, ad esempio lo faccio per dati meteorologici recenti non storici o ricerche recenti di feed di notizie o dati di punti dati recenti sulla posizione GPS.

Questo è un enorme miglioramento delle prestazioni se sai per certo che le tue righe sono, ad esempio, nel TOP 5% più recente della tabella. Tale che, anche se ci sono indici sulle tabelle, limita ulteriormente le possibilità solo al 5% delle righe nelle tabelle che hanno 100+ milioni o 1+ miliardi di righe. Ciò è particolarmente vero quando i dati precedenti richiedono letture del disco fisico e non solo letture della memoria logica .

Questo è molto più efficiente di SELECT TOP | PERCENTO | LIMIT in quanto 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'

-1

Per visualizzare le ultime 3 righe senza usare 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
Ciò non fornirà risultati prevedibili. Secondo i documenti MSDN di SQL Server ( msdn.microsoft.com/en-us/library/ms189463.aspx ): "Quando TOP viene utilizzato insieme alla clausola ORDER BY, il set di risultati è limitato al primo N numero di ordinato righe; in caso contrario, restituisce il primo N numero di righe in un ordine indefinito. "
caveman_dick,

-1

Prova a usare la EXCEPTsintassi.
Qualcosa come questo:

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

Stessa risposta di @Prafulla Sutradhar
DMK

-1

Forse un po 'in ritardo, ma ecco una semplice selezione che risolve la tua domanda.

SELECT * FROM "TABLE" T ORDER BY "T.ID_TABLE" DESC LIMIT 5;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.