MySQL: pobierz najnowszy rekord


80

Jak w poniższej tabeli mogę uzyskać tylko najnowszy rekord z id=1kolumny logowania, a nie wszystkie 3 rekordy?

+----+---------------------+---------+
| id | signin              | signout |
+----+---------------------+---------+
|  1 | 2011-12-12 09:27:24 | NULL    |
|  1 | 2011-12-13 09:27:31 | NULL    |
|  1 | 2011-12-14 09:27:34 | NULL    |
|  2 | 2011-12-14 09:28:21 | NULL    |
+----+---------------------+---------+

Odpowiedzi:


90

Użyj agregatu MAX(signin)pogrupowanego według identyfikatora. Spowoduje to wyświetlenie najnowszych signindla każdego id.

SELECT 
 id, 
 MAX(signin) AS most_recent_signin
FROM tbl
GROUP BY id

Aby uzyskać cały pojedynczy rekord, wykonaj INNER JOINzapytanie względem podzapytania, które zwraca tylko MAX(signin)identyfikator według.

SELECT 
  tbl.id,
  signin,
  signout
FROM tbl
  INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id
  ) ms ON tbl.id = ms.id AND signin = maxsign
WHERE tbl.id=1

Oto, co zadziałało w oparciu o twoją pierwszą odpowiedź:SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;
enchance

Próbowałem wdrożyć drugie rozwiązanie (aby uzyskać cały wiersz) w swojej własnej sytuacji, ale zawsze otrzymuję pusty zestaw wyników
rantsh

Odpowiedź @rantsh xQbert miała poprawną wersję tego, co pierwotnie miałem powyżej, ale wolę rozwiązanie, które po prostu zmieniłem.
Michael Berkowski

@MichaelBerkowski chodziło Ci o to, że wolisz moje rozwiązanie? Nie miałbym nic przeciwko uzyskaniu głosu za moją odpowiedź, jeśli tak jest
rantsh

1
@rantsh Ach, nie zauważyłem, że dodałeś coś podobnego do tego, co właśnie zmodyfikowałem, z wyjątkiem via USINGzamiast jawnego ON. Dostałeś +1 :)
Michael Berkowski

83
SELECT *
FROM   tbl
WHERE  id = 1
ORDER  BY signin DESC
LIMIT  1;

Oczywistym wskaźnik będzie na (id), lub indeks wielokolumnowa na (id, signin DESC).

Dogodnie dla tego przypadku MySQL sortuje ostatnieNULL wartości w porządku malejącym. To jest to, czego zazwyczaj potrzebujesz, jeśli mogą istnieć wartości: wiersz z najnowszą wartością niezerową .NULLsignin

Aby NULLnajpierw uzyskać wartości:

ORDER BY signin IS NOT NULL, signin DESC

Związane z:

Standard SQL nie definiuje jawnie domyślnej kolejności sortowania NULLwartości. Zachowanie różni się nieco w różnych systemach RDBMS. Widzieć:

Ale nie to NULLS FIRST/ NULLS LASTklauzule zdefiniowane w standardzie SQL i obsługiwane przez większość dużych RDBMS, ale nie przez MySQL. Widzieć:


5
To najczystszy sposób na zrobienie tego!
karancan

Zastanów się nad utworzeniem indeksu dla kolumny logowania, znacznie przyspieszy to proces
Alexei Tenitski

Użyj SELECT TOP 1 *i usuń LIMIT 1ostatnią linię. jeśli używasz SQL Server. Użyj powyższego, jeśli MySQL lub Postgres.
jaredbaszler

Najczystsze. . . . . . . .
stigzler

Proste i czyste!
Jeremy Swagger

9

Opierając się na odpowiedziach @ xQbert, możesz uniknąć podzapytania ORAZ sprawić, że będzie wystarczająco ogólne, aby filtrować według dowolnego identyfikatora

SELECT id, signin, signout
FROM dTable
INNER JOIN(
  SELECT id, MAX(signin) AS signin
  FROM dTable
  GROUP BY id
) AS t1 USING(id, signin)

Cześć, jak działa to zapytanie i czy jest bardziej wydajne niż odpowiedź xQberta? Oba zapytania są uruchamiane mniej więcej w tym samym czasie i nie rozumiem, jak część zapytania zastępuje to, co zwykle i jest włączone.
ZJS

3
Select [insert your fields here]
from tablename 
where signin = (select max(signin) from tablename where ID = 1)


1

Miałem podobny problem. Musiałem uzyskać ostatnią wersję tłumaczenia zawartości strony, innymi słowy - uzyskać ten konkretny rekord, który ma najwyższą liczbę w kolumnie wersji. Więc wybieram wszystkie rekordy uporządkowane według wersji, a następnie biorę pierwszy wiersz z wyniku (za pomocą klauzuli LIMIT).

SELECT *
FROM `page_contents_translations`
ORDER BY version DESC
LIMIT 1

1

Prosty sposób na osiągnięcie

Wiem, że to stare pytanie. Możesz też zrobić coś takiego

SELECT * FROM Table WHERE id=1 ORDER BY signin DESC

W powyższym zapytaniu pierwszy rekord będzie najnowszym rekordem.

Tylko dla jednego rekordu możesz użyć czegoś takiego

SELECT top(1) * FROM Table WHERE id=1 ORDER BY signin DESC

Powyższe zapytanie zwróci tylko jeden najnowszy rekord.

Twoje zdrowie!

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.