@AlirezaSoori: Trotz des Namens idist nur eine Spalte in einer Tabelle. Es gibt keine Garantie dafür, dass die Werte in der idSpalte eindeutig sein müssen.
Unutbu
1
@unutbu Angenommen, dies idist kein Primär- oder eindeutiger Schlüssel :) Angesichts des Namens besteht eine vernünftige Chance, dass dies der Fall ist. Es ist auch erwähnenswert, dass der Ansatz mit der Unterauswahl je nach verwendetem DBMS möglicherweise viel weniger effizient ist.
Michael Mior
3
@MichaelMior: idkönnte ein Fremdschlüssel sein, in diesem Fall ist er möglicherweise nicht eindeutig. Ich habe ein Benchmarking set profiling = 1; ...; show profilesmit MySQL durchgeführt und es scheint, dass unsere Lösungen mit MySQL die gleiche Leistung haben. Wissen Sie nach meinem eigenen Wissen, welches DBMS für Unterauswahlen eine schlechtere Leistung aufweist?
Unutbu
1
Es könnte ein Fremdschlüssel sein, aber wie gesagt, ich vermute nur anhand des Namens, dass dies nicht der Fall ist. Es ist historisch bekannt, dass MySQL bei Unterauswahlen eine schlechte Leistung aufweist. In neueren Versionen hat sich dies jedoch erheblich verbessert. Dies hängt also davon ab, welche Version Sie verwenden. Wenn Sie es jedoch überdenken, ist diese spezielle Abfrage möglicherweise in Ordnung. Obwohl das mehrmalige Ausführen einer Abfrage mit Profilerstellung nicht unbedingt viel über die relative Leistung aussagt.
Michael Mior
149
Sie könnten auch tun
SELECTrowFROMtableORDERBY id DESC LIMIT 1;
Dadurch werden die Zeilen in absteigender Reihenfolge nach ihrer ID sortiert und die erste Zeile zurückgegeben. Dies entspricht der Rückgabe der Zeile mit der maximalen ID. Dies setzt natürlich voraus, dass dies idin allen Zeilen eindeutig ist. Andernfalls kann es mehrere Zeilen mit dem Maximalwert für geben, idund Sie erhalten nur eine.
Um genau das zu tun, was das OP verlangt, würde ich dies tun. Aber die anderen Antworten bieten eine bessere Ausbildung in SQL-Struktur :)
MatBailie
@Dems Wie so? Zu keiner anderen Antwort werden Erklärungen abgegeben? Ich bin natürlich auch daran schuld :(
Michael Mior
Nur dass andere Fragen die Syntax korrigieren, ohne die Logik neu zu gestalten. Das OP lernt also, wie man diese bestimmte SQL korrekt angibt.
MatBailie
Fairer Punkt :) Obwohl andere Antworten die Logik wohl immer noch korrigieren.
Michael Mior
Was ist mit Leistung? Ich bin mit dieser Art von Abfrage hierher gekommen, die bereits für mich funktioniert hat, aber ich habe mich gefragt, ob das der richtige Weg ist. Ist ORDER BY nicht eine O (n * log n) -Operation?
Dhill
27
SELECT*FROMtableWHERE id =(SELECT MAX(id)FROMTABLE)
@ shA.t SELECT entry FROM table WHERE id = MAX(id)würde nicht funktionieren ?!
Oldboy
@ shA.t Außerdem versuche ich so etwas wie das Folgende zu tun: SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)wobei ich nur entry_timeden neuesten Eintrag in der Datenbank brauche . Ist diese Aussage ausreichend oder sollte es sein:SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
Oldboy
Es gibt keine vertrauenswürdige Bedeutung für den letzten Eintrag in einem Abfrageergebnis. Sie benötigen ein Feld für die Einfügezeit usw. Übrigens, bitte stellen Sie Ihre Frage separat, ich hoffe, Sie werden mehr Aufmerksamkeit bekommen -HTH;).
shA.t
17
Sie können nicht geben, order byweil order byein "vollständiger Scan" auf einer Tabelle durchgeführt wird.
Die folgende Abfrage ist besser:
SELECT*FROMtableWHERE id =(SELECT MAX(id)FROMtable);
ORDER BYführt keinen vollständigen Scan durch, wenn Sie davon ausgehen, dass dies idder Primärschlüssel der Tabelle ist. (Und wenn nicht, ist es ziemlich schlecht benannt.) Wenn nicht, wie erwarten Sie MAX(id), ohne einen vollständigen Tabellenscan zu arbeiten? Wenn kein Index vorhanden ist, muss noch jeder Wert überprüft werden, um das Maximum zu ermitteln.
Michael Mior
@CakeLikeBoss gut, ich habe tatsächlich versucht, "order by" -Abfrage und Ihre "SELECT * FROM-Tabelle WHERE id = (SELECT MAX (id) FROM-Tabelle);" Abfrage über eine Tabelle mit 114 Zeilen, während diese Abfrage jedes Mal genau 0,0004 Sekunden dauerte, während die zweite Abfrage von 0,0007 bis 0,0010 Sekunden dauerte. Ich wiederholte dies mehrmals
prabhjot
0
Versuchen Sie es damit
SELECTtop1 id, Col2, row_number()over(orderby id desc)FROMTable
Das Schlüsselwort TOP funktioniert in MySQL nicht. Diese Abfrage funktioniert nicht.
Anirudha Gupta
@toddmo: MySQL! Und SQL-Server ist auch für andere Menschen nicht hilfreich. Du meinst MS-SQL?
Raiserle
@raiserle, können Sie mir helfen, herauszufinden, wo ich zu dieser Frage etwas kommentiert oder gepostet habe? Ich kann meinen Namen an dieser Frage nirgendwo sehen.
Toddmo
0
Man kann sich auch immer für analytische Funktionen entscheiden, die Ihnen mehr Kontrolle geben
select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1
Wenn Sie je nach Datentyp Probleme mit der Funktion rank () haben, können Sie auch zwischen row_number () und dens_rank () wählen.
Antworten:
Sie könnten eine Unterauswahl verwenden:
Beachten Sie, dass
max(id)
mehrere Zeilen zurückgegeben werden , wenn der Wert von nicht eindeutig ist.Wenn Sie nur eine solche Zeile möchten, verwenden Sie die Antwort von @ MichaelMior.
quelle
id
ist nur eine Spalte in einer Tabelle. Es gibt keine Garantie dafür, dass die Werte in derid
Spalte eindeutig sein müssen.id
ist kein Primär- oder eindeutiger Schlüssel :) Angesichts des Namens besteht eine vernünftige Chance, dass dies der Fall ist. Es ist auch erwähnenswert, dass der Ansatz mit der Unterauswahl je nach verwendetem DBMS möglicherweise viel weniger effizient ist.id
könnte ein Fremdschlüssel sein, in diesem Fall ist er möglicherweise nicht eindeutig. Ich habe ein Benchmarkingset profiling = 1; ...; show profiles
mit MySQL durchgeführt und es scheint, dass unsere Lösungen mit MySQL die gleiche Leistung haben. Wissen Sie nach meinem eigenen Wissen, welches DBMS für Unterauswahlen eine schlechtere Leistung aufweist?Sie könnten auch tun
Dadurch werden die Zeilen in absteigender Reihenfolge nach ihrer ID sortiert und die erste Zeile zurückgegeben. Dies entspricht der Rückgabe der Zeile mit der maximalen ID. Dies setzt natürlich voraus, dass dies
id
in allen Zeilen eindeutig ist. Andernfalls kann es mehrere Zeilen mit dem Maximalwert für geben,id
und Sie erhalten nur eine.quelle
quelle
SELECT entry FROM table WHERE id = MAX(id)
würde nicht funktionieren ?!SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)
wobei ich nurentry_time
den neuesten Eintrag in der Datenbank brauche . Ist diese Aussage ausreichend oder sollte es sein:SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
Sie können nicht geben,
order by
weilorder by
ein "vollständiger Scan" auf einer Tabelle durchgeführt wird.Die folgende Abfrage ist besser:
quelle
ORDER BY
führt keinen vollständigen Scan durch, wenn Sie davon ausgehen, dass diesid
der Primärschlüssel der Tabelle ist. (Und wenn nicht, ist es ziemlich schlecht benannt.) Wenn nicht, wie erwarten SieMAX(id)
, ohne einen vollständigen Tabellenscan zu arbeiten? Wenn kein Index vorhanden ist, muss noch jeder Wert überprüft werden, um das Maximum zu ermitteln.Versuchen Sie es damit
quelle
Man kann sich auch immer für analytische Funktionen entscheiden, die Ihnen mehr Kontrolle geben
select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1
Wenn Sie je nach Datentyp Probleme mit der Funktion rank () haben, können Sie auch zwischen row_number () und dens_rank () wählen.
quelle