Jak wybrać cały wiersz, który ma największy identyfikator w tabeli?


Odpowiedzi:


228

Możesz użyć podselekcji:

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

Zwróć uwagę, że jeśli wartość max(id)nie jest unikalna, zwracanych jest wiele wierszy.

Jeśli chcesz tylko jeden taki wiersz, użyj odpowiedzi @ MichaelMior,

SELECT row from table ORDER BY id DESC LIMIT 1

6
@AlirezaSoori: Pomimo nazwy, idto tylko kolumna w tabeli. Nie ma gwarancji, że wartości w idkolumnie muszą być unikalne.
unutbu

1
@unutbu Zakładając, że idnie jest to klucz podstawowy ani unikalny :) Biorąc pod uwagę nazwę, istnieje duża szansa, że ​​tak jest. Warto również zauważyć, że w zależności od używanego DBMS, podejście z podselektem może być znacznie mniej wydajne.
Michael Mior,

3
@MichaelMior: idmoże być kluczem obcym, w takim przypadku może nie być unikatowy. Przeprowadziłem kilka testów porównawczych set profiling = 1; ...; show profilesi wygląda na to, że nasze rozwiązania mają taką samą wydajność przy użyciu MySQL. Z mojej własnej wiedzy, czy wiesz, który DBMS ma gorszą wydajność dla podselekcji?
unutbu

1
Może to być klucz obcy, ale jak powiedziałem, po prostu zgaduję na podstawie nazwy, że tak nie jest. MySQL jest historycznie znany ze słabej wydajności w przypadku podselekcji. To znacznie się poprawiło w nowszych wersjach, więc zależy od używanej wersji. Jednak po ponownym przemyśleniu to konkretne zapytanie może być OK. Chociaż kilkakrotne wykonanie zapytania z profilowaniem niekoniecznie mówi wiele o względnej wydajności.
Michael Mior,

149

Ty też możesz to zrobić

SELECT row FROM table ORDER BY id DESC LIMIT 1;

Spowoduje to posortowanie wierszy według ich identyfikatorów w porządku malejącym i zwrócenie pierwszego wiersza. To to samo, co zwrócenie wiersza z maksymalnym identyfikatorem. To oczywiście zakłada, że idjest wyjątkowy wśród wszystkich rzędów. W przeciwnym razie może istnieć wiele wierszy z maksymalną wartością dla, ida otrzymasz tylko jeden.


Aby konkretnie zrobić to, o co prosi OP, zrobiłbym to. Ale inne odpowiedzi zapewniają lepszą edukację na temat struktury SQL :)
MatBailie

@Dems Jak to? Nie podano żadnych wyjaśnień na temat innej odpowiedzi? Oczywiście ja też jestem temu winny :(
Michael Mior

Tylko te inne pytania poprawiają składnię bez refaktoryzacji logiki. Tak więc OP uczy się, jak poprawnie określić ten konkretny plik sql.
MatBailie

Słuszna uwaga :) Chociaż inne odpowiedzi prawdopodobnie nadal poprawiają logikę.
Michael Mior,

A co z wydajnością? Dostałem się tutaj z tego rodzaju zapytaniem, które już dla mnie działa, ale zastanawiałem się, czy to właściwy sposób. Czy ORDER BY nie jest operacją 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)nie zadziała ?!
oldboy

@ shA.t Ponadto próbuję zrobić coś takiego: SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)przy czym potrzebuję tylko entry_timenajnowszego wpisu w bazie danych. Czy to stwierdzenie jest wystarczające, czy powinno być:SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
oldboy

Najnowszy wpis w wyniku zapytania nie ma zaufanego znaczenia, musisz mieć pole czasu wstawienia i tak dalej. Swoją drogą proszę o pytanie zadaj osobno, mam nadzieję, że zdobędziesz więcej uprzejmości -HTH;).
shA.t

17

Nie możesz dać, order byponieważ order byrobi "pełne skanowanie" na stole.

Następujące zapytanie jest lepsze:

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

18
ORDER BYnie wykona pełnego skanowania, jeśli założysz, że idjest to klucz podstawowy tabeli. (A jeśli tak nie jest, jest raczej słabo nazwane). Jeśli nie, jak spodziewasz MAX(id)się pracy bez pełnego skanowania tabeli? Jeśli nie ma indeksu, każda wartość musi zostać sprawdzona, aby znaleźć maksimum.
Michael Mior

@CakeLikeBoss No cóż, wypróbowałem zapytanie „order by” i twoje „SELECT * FROM table WHERE id = (SELECT MAX (id) FROM table);” zapytanie w tabeli 114 wierszy, podczas gdy to zapytanie trwało dokładnie 0,0004 sekundy za każdym razem, podczas gdy drugie zapytanie trwało od 0,0007 do 0,0010 sekund Powtórzyłem to kilka razy
prabhjot

1

Zawsze można też skorzystać z funkcji analitycznych, które zapewnią większą kontrolę

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

Jeśli napotkasz problem z funkcją rank () w zależności od typu danych, możesz również wybrać row_number () lub dense_rank ().


0

Spróbuj z tym

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

9
Słowo kluczowe TOP nie działa w MySQL. To zapytanie nie zadziała.
Anirudha Gupta

@toddmo: MySQL! Sql-Server również nie jest pomocny dla innych osób. Masz na myśli MS-SQL?
raiserle

@raiserle, czy możesz mi pomóc znaleźć miejsce, w którym skomentowałem lub opublikowałem cokolwiek na to pytanie? Nigdzie nie widzę swojego nazwiska dołączonego do tego pytania.
toddmo,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.