Jak uzyskać najnowszy rekord w każdej grupie za pomocą GROUP BY?

Załóżmy, że mam tabelę o nazwie messages z kolumnami:

id | from_id | to_id | subject | message | timestamp

Chcę otrzymywać najnowsze wiadomości od każdego użytkownika tylko, jak widać w skrzynce odbiorczej FaceBook zanim przejdziesz do rzeczywistego wątku.

To zapytanie wydaje mi się zbliżać do wyniku, którego potrzebuję:

SELECT * FROM messages GROUP BY from_id

Jednak zapytanie daje mi najstarszą wiadomość od każdego użytkownika, a nie najnowszą.

Nie mogę tego rozgryźć.
Author: Jonathan Leffler, 2012-06-12

6 answers

Powinieneś znaleźć ostatnie timestamp wartości w każdej grupie (subquery), a następnie dołączyć to subquery do Tabeli -

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;
 77
Author: Devart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-12 15:18:47

Spróbuj tego

SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc
 13
Author: Venu M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-21 18:40:48

To zapytanie zwraca ostatni rekord dla każdego Formula_id:

    SELECT m1.*
     FROM messages m1 LEFT JOIN messages m2
     ON (m1.Form_id = m2.Form_id AND m1.id < m2.id)
     WHERE m2.id IS NULL;
 2
Author: leyla azari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 07:22:38

To standardowy problem.

Zauważ, że MySQL pozwala na pominięcie kolumn z klauzuli GROUP BY, czego Standardowy SQL nie robi, ale nie uzyskuje się deterministycznych wyników w ogóle podczas korzystania z obiektu MySQL.

SELECT *
  FROM Messages AS M
  JOIN (SELECT To_ID, From_ID, MAX(TimeStamp) AS Most_Recent
          FROM Messages
         WHERE To_ID = 12345678
         GROUP BY From_ID
       ) AS R
    ON R.To_ID = M.To_ID AND R.From_ID = M.From_ID AND R.Most_Recent = M.TimeStamp
 WHERE M.To_ID = 12345678

Dodałem Filtr To_ID, aby dopasować to, co prawdopodobnie masz. Zapytanie będzie działać bez niego, ale zwróci znacznie więcej danych w ogóle. Warunek nie powinien być podany zarówno w zapytaniu zagnieżdżonym, jak i zewnętrznym (optymalizator należy nacisnąć warunek automatycznie), ale powtórzenie warunku, jak pokazano, nie może zaszkodzić.

 1
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-12 15:18:57

Uzupełniając to, co powiedział Devart, poniższy kod nie porządkuje zgodnie z pytaniem:

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;

Klauzula "GROUP BY" musi znajdować się w głównym zapytaniu, ponieważ najpierw musimy zmienić kolejność "źródła", aby uzyskać potrzebne "grupowanie" tak:

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages ORDER BY timestamp DESC) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp GROUP BY t2.timestamp;

Pozdrawiam,

 1
Author: Bruno de Oliveira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 13:53:42

Musisz je zamówić.

SELECT * FROM messages GROUP BY from_id ORDER BY timestamp DESC LIMIT 1

 -4
Author: Marcus Recck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-12 15:12:14