Risposte:
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
Non è necessario. È possibile utilizzare un ORDER BYe modificare l'ordinamento in DESCper ottenere lo stesso effetto.
Scusa, ma non credo di vedere risposte corrette secondo me.
La TOPfunzione x mostra i record in un ordine indefinito. Da quella definizione segue che una BOTTOMfunzione non può essere definita.
Indipendente da qualsiasi indice o ordinamento. Quando esegui una ORDER BY y DESC, ottieni prima le righe con il valore y più alto. Se si tratta di un ID generato automaticamente, dovrebbe mostrare gli ultimi record aggiunti alla tabella, come suggerito nelle altre risposte. Però:
TOPfunzioneLa risposta corretta dovrebbe essere che non esiste e non può esserci un equivalente TOPper ottenere le righe inferiori.
Logicamente,
BOTTOM (x) is all the records except TOP (n - x), where n is the count; x <= n
Ad esempio, seleziona gli ultimi 1000 da dipendente:
In T-SQL,
DECLARE
@bottom int,
@count int
SET @bottom = 1000
SET @count = (select COUNT(*) from Employee)
select * from Employee emp where emp.EmployeeID not in
(
SELECT TOP (@count-@bottom) Employee.EmployeeID FROM Employee
)
Sembrerebbe che nessuna delle risposte che implementano una clausola ORDER BY nella soluzione manchi il punto, o non capisca effettivamente cosa ti restituisce TOP.
TOP restituisce un set di risultati della query non ordinato che limita il set di record ai primi N record restituiti. (Dal punto di vista di Oracle, è simile all'aggiunta di un punto in cui ROWNUM <(N + 1).
Qualsiasi soluzione che utilizza un ordine, può restituire righe che vengono anche restituite dalla clausola TOP (poiché tale set di dati non era ordinato in primo luogo), a seconda di quali criteri sono stati utilizzati nell'ordine da
L'utilità di TOP è che una volta che il set di dati raggiunge una certa dimensione N, smette di recuperare le righe. Puoi avere un'idea dell'aspetto dei dati senza doverli recuperare tutti.
Per implementare BOTTOM in modo accurato, è necessario recuperare l'intero set di dati non ordinato e quindi limitare il set di dati agli N record finali. Ciò non sarà particolarmente efficace se hai a che fare con tavoli enormi. Né ti darà necessariamente quello che pensi di chiedere. La fine del set di dati potrebbe non essere necessariamente "le ultime righe inserite" (e probabilmente non lo sarà per la maggior parte delle applicazioni DML intensive).
Allo stesso modo, le soluzioni che implementano un ORDER BY sono, sfortunatamente, potenzialmente disastrose quando si tratta di grandi set di dati. Se ho, diciamo, 10 miliardi di record e voglio gli ultimi 10, è piuttosto sciocco ordinare 10 miliardi di record e selezionare gli ultimi 10.
Il problema qui è che BOTTOM non ha il significato che noi pensiamo quando lo confrontiamo con TOP.
Quando i record vengono inseriti, cancellati, inseriti, cancellati più e più volte, alcuni spazi verranno visualizzati nella memoria e successivamente, se possibile, verranno inserite delle righe. Ma quello che vediamo spesso, quando selezioniamo TOP, appare essere un dato ordinato, perché potrebbe essere stato inserito all'inizio dell'esistenza della tabella. Se la tabella non presenta molte eliminazioni, potrebbe essere visualizzato ordinata. (ad esempio, le date di creazione possono essere indietro nel tempo quanto la creazione della tabella stessa). Ma la realtà è che, se si tratta di una tabella che richiede molte operazioni di eliminazione, le prime N righe potrebbero non essere affatto così.
Quindi, la linea di fondo qui (gioco di parole) è che qualcuno che sta chiedendo i record BOTTOM N in realtà non sa cosa sta chiedendo. O, almeno, quello che stanno chiedendo e quello che in realtà significa BOTTOM non sono la stessa cosa.
Quindi, la soluzione può soddisfare le effettive esigenze aziendali del richiedente ... ma non soddisfa i criteri per essere INFERIORE.
insertistruzione per inserire le righe in una tabella grande e non indicizzata. (Sto popolando la tabella prima di iniziare a indicizzarla.) Ho perso la mia sessione client a causa di un riavvio o altro, e ora voglio vedere se le mie righe appena aggiunte sono lì. Se la riga "inferiore" della tabella è una delle mie recenti, so che l'operazione è stata completata. Se la riga 'inferiore' è qualcos'altro, beh non ci sono garanzie e devo scansionare l'intera tabella per assicurarmene ... ma molto probabilmente potrei risparmiare un po 'di tempo controllando rapidamente la' parte inferiore 'proprio come puoi fare tu' superiore'.
La risposta attualmente accettata da "Justin Ethier" non è una risposta corretta come sottolineato da "Protector one".
Per quanto posso vedere, per ora, nessun'altra risposta o commento fornisce l'equivalente di BOTTOM (x) richiesto dall'autore della domanda.
Per prima cosa, consideriamo uno scenario in cui sarebbe necessaria questa funzionalità:
SELECT * FROM Split('apple,orange,banana,apple,lime',',')
Ciò restituisce una tabella di una colonna e cinque record:
Come puoi vedere: non abbiamo una colonna ID; non possiamo ordinare in base alla colonna restituita; e non possiamo selezionare gli ultimi due record utilizzando SQL standard come possiamo fare per i primi due record.
Ecco il mio tentativo di fornire una soluzione:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
SELECT TOP 2 * FROM #mytemptable ORDER BY tempID DESC
DROP TABLE #mytemptable
Ed ecco una soluzione più completa:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
DELETE FROM #mytemptable WHERE tempID <= ((SELECT COUNT(*) FROM #mytemptable) - 2)
ALTER TABLE #mytemptable DROP COLUMN tempID
SELECT * FROM #mytemptable
DROP TABLE #mytemptable
Non sto affatto affermando che questa sia una buona idea da usare in tutte le circostanze, ma fornisce i risultati desiderati.
Tutto quello che devi fare è invertire il tuo ORDER BY. Aggiungi o rimuovi DESCad esso.
Il problema con l'ordinamento nell'altro modo è che spesso non fa buon uso degli indici. Inoltre, non è molto estendibile se è necessario selezionare un numero di righe che non sono all'inizio o alla fine. Un modo alternativo è il seguente.
DECLARE @NumberOfRows int;
SET @NumberOfRows = (SELECT COUNT(*) FROM TheTable);
SELECT col1, col2,...
FROM (
SELECT col1, col2,..., ROW_NUMBER() OVER (ORDER BY col1) AS intRow
FROM TheTable
) AS T
WHERE intRow > @NumberOfRows - 20;
La risposta "Tom H" sopra è corretta e funziona per me nell'ottenere le 5 righe inferiori.
SELECT [KeyCol1], [KeyCol2], [Col3]
FROM
(SELECT TOP 5 [KeyCol1],
[KeyCol2],
[Col3]
FROM [dbo].[table_name]
ORDER BY [KeyCol1],[KeyCol2] DESC) SOME_ALAIS
ORDER BY [KeyCol1],[KeyCol2] ASC
Grazie.
prova questo.
declare @floor int --this is the offset from the bottom, the number of results to exclude
declare @resultLimit int --the number of results actually retrieved for use
declare @total int --just adds them up, the total number of results fetched initially
--following is for gathering top 60 results total, then getting rid of top 50. We only keep the last 10
set @floor = 50
set @resultLimit = 10
set @total = @floor + @resultLimit
declare @tmp0 table(
--table body
)
declare @tmp1 table(
--table body
)
--this line will drop the wanted results from whatever table we're selecting from
insert into @tmp0
select Top @total --what to select (the where, from, etc)
--using floor, insert the part we don't want into the second tmp table
insert into @tmp1
select top @floor * from @tmp0
--using select except, exclude top x results from the query
select * from @tmp0
except
select * from @tmp1
Ho trovato una soluzione a questo che non richiede di conoscere il numero di righe restituite.
Ad esempio, se desideri ottenere tutte le posizioni registrate in una tabella, tranne l'ultima 1 (o 2, o 5 o 34)
SELECT *
FROM
(SELECT ROW_NUMBER() OVER (ORDER BY CreatedDate) AS Row, *
FROM Locations
WHERE UserId = 12345) AS SubQuery
WHERE Row > 1 -- or 2, or 5, or 34
SELECT TOP 10*from TABLE1 ORDER BY ID DESC
Dove ID è la chiave primaria di TABLE1.
Innanzitutto, crea un indice in una sottoquery secondo l'ordine originale della tabella utilizzando:
ROW_NUMBER () OVER (ORDER BY (SELECT NULL) ) AS RowIndex
Quindi ordina la tabella in modo discendente dalla RowIndexcolonna che hai creato nella query principale:
ORDER BY RowIndex DESC
E infine usa TOPcon la quantità di righe desiderata:
SELECT TOP 1 * --(or 2, or 5, or 34)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL) ) AS RowIndex, *
FROM MyTable) AS SubQuery
ORDER BY RowIndex DESC