Come faccio a selezionare un'intera riga con l'ID più grande nella tabella?


Risposte:


228

È possibile utilizzare una sottoselezione:

SELECT row 
FROM table 
WHERE id=(
    SELECT max(id) FROM table
    )

Se il valore di max(id)non è univoco, vengono restituite più righe.

Se vuoi solo una di queste righe, usa la risposta di @ MichaelMior,

SELECT row from table ORDER BY id DESC LIMIT 1

6
@AlirezaSoori: Nonostante il nome, idè solo una colonna in una tabella. Non vi è alcuna garanzia che i valori nella idcolonna debbano essere univoci.
unutbu,

1
@unutbu Supponendo che idnon sia una chiave primaria o unica :) Dato il nome, c'è una ragionevole possibilità che lo sia. Vale anche la pena notare che, a seconda del DBMS in uso, l'approccio con la sottoselezione potrebbe essere molto meno efficiente.
Michael Mior,

3
@MichaelMior: idpotrebbe essere una chiave esterna, nel qual caso potrebbe non essere unica. Ho fatto alcuni benchmarking usando set profiling = 1; ...; show profilese sembra che le nostre soluzioni abbiano le stesse prestazioni usando MySQL. Per quanto ne so, sai quali DBMS ha prestazioni più scarse per le sottoselezioni?
unutbu,

1
Potrebbe essere una chiave esterna, ma come ho detto, sto solo indovinando in base al nome che non lo è. MySQL è storicamente noto per avere scarse prestazioni con le sottoselezioni. Ciò è notevolmente migliorato nelle versioni più recenti, quindi dipende dalla versione che stai utilizzando. Tuttavia, ripensandoci, questa particolare query potrebbe essere OK. Anche se eseguire una query un paio di volte con la profilazione non dice necessariamente molto sulle prestazioni relative.
Michael Mior,

149

Potresti anche fare

SELECT row FROM table ORDER BY id DESC LIMIT 1;

Ciò ordinerà le righe in base al loro ID in ordine decrescente e restituirà la prima riga. Ciò equivale a restituire la riga con l'ID massimo. Questo ovviamente presuppone che idsia unico tra tutte le righe. Altrimenti potrebbero esserci più righe con il valore massimo per ide ne otterrai solo una.


Per fare specificamente ciò che l'OP chiede, farei questo. Ma le altre risposte forniscono una migliore istruzione sulla struttura SQL :)
MatBailie,

@Dems Come mai? Non vengono fornite spiegazioni su altre risposte? Naturalmente sono anche colpevole di questo :(
Michael Mior,

Solo che altre domande correggono la sintassi senza riformattare la logica. Quindi, l'OP impara come dichiarare correttamente quello specifico sql.
MatBailie,

Punto giusto :) Anche se altre risposte stanno probabilmente ancora correggendo la logica.
Michael Mior,

Che dire delle prestazioni? Sono arrivato qui con questo tipo di query già funzionante per me, ma mi chiedevo se fosse la strada giusta. ORDER BY non è un'operazione O (n * log n)?
dhill

27
SELECT * 
FROM table 
WHERE id = (SELECT MAX(id) FROM TABLE)

@ shA.t SELECT entry FROM table WHERE id = MAX(id)non funzionerebbe ?!
oldboy

@ shA.t Inoltre, quello che sto cercando di fare qualcosa di simile al seguente: SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)per cui ho solo bisogno entry_timedella voce più recente nel database. SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
Questa

Non esiste un significato attendibile per la voce più recente in un risultato della query, è necessario disporre di un campo per il tempo di inserimento e così via. A proposito, per favore fai la tua domanda separatamente, spero che otterrai più attenzioni -HTH;).
shA.t

17

Non puoi dare order byperché order byesegue una "scansione completa" su una tabella.

La seguente query è migliore:

SELECT * FROM table WHERE id = (SELECT MAX(id) FROM table);

18
ORDER BYnon eseguirà una scansione completa se si presume che idsia la chiave primaria della tabella. (E se non lo è, ha un nome piuttosto scadente.) In caso contrario, come ti aspetti MAX(id)di lavorare senza una scansione completa della tabella? Se non è presente alcun indice, è necessario verificare ogni valore per trovare il massimo.
Michael Mior,

@CakeLikeBoss bene ho effettivamente provato la query "ordina per" e la tua "SELEZIONA * DA tabella DOVE id = (SELEZIONA MAX (id) DA tabella);" query su una tabella di 114 righe mentre questa query impiegava esattamente 0,0004 secondi ogni volta mentre la seconda query impiegava da 0,0007 a 0,0010 secondi che ho ripetuto più volte
prabhjot

1

Si può sempre andare anche per le funzioni analitiche che ti daranno un maggiore controllo

select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1

Se hai problemi con la funzione rank () a seconda del tipo di dati, puoi scegliere anche da row_number () o dense_rank ().


0

Prova con questo

 SELECT top 1  id, Col2,  row_number() over (order by id desc)  FROM Table

9
La parola chiave TOP non funziona in MySQL. Questa query non funzionerà.
Anirudha Gupta,

@toddmo: MySQL! E SQL Server non è utile anche per altre persone. Intendi MS-SQL?
Raiserle,

@raiserle, puoi aiutarmi a trovare dove ho commentato o pubblicato qualcosa su questa domanda? Non riesco a vedere il mio nome allegato a questa domanda da nessuna parte.
toddmo,
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.