How to get the latest record in each group using GROUP BY?

MysqlSqlGreatest N-per-Group

Mysql Problem Overview


Let's say I have a table called messages with the columns:

id | from_id | to_id | subject | message | timestamp

I want to get the latest message from each user only, like you would see in your FaceBook inbox before you drill down into the actual thread.

This query seems to get me close to the result I need:

SELECT * FROM messages GROUP BY from_id

However the query is giving me the oldest message from each user and not the newest.

I can't figure this one out.

Mysql Solutions


Solution 1 - Mysql

You should find out last timestamp values in each group (subquery), and then join this subquery to the table -

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;

Solution 2 - Mysql

Try this

SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc

Solution 3 - Mysql

this query return last record for every Form_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;

Solution 4 - Mysql

Just complementing what Devart said, the below code is not ordering according to the question:

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;

The "GROUP BY" clause must be in the main query since that we need first reorder the "SOURCE" to get the needed "grouping" so:

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;

Regards,

Solution 5 - Mysql

This is a standard problem.

Note that MySQL allows you to omit columns from the GROUP BY clause, which Standard SQL does not, but you do not get deterministic results in general when you use the MySQL facility.

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

I've added a filter on the To_ID to match what you're likely to have. The query will work without it, but will return a lot more data in general. The condition should not need to be stated in both the nested query and the outer query (the optimizer should push the condition down automatically), but it can do no harm to repeat the condition as shown.

Solution 6 - Mysql

You need to order them.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1019144View Question on Stackoverflow
Solution 1 - MysqlDevartView Answer on Stackoverflow
Solution 2 - MysqlVenu MorigadiView Answer on Stackoverflow
Solution 3 - Mysqlleyla azariView Answer on Stackoverflow
Solution 4 - MysqlBruno de OliveiraView Answer on Stackoverflow
Solution 5 - MysqlJonathan LefflerView Answer on Stackoverflow
Solution 6 - MysqlMarcus RecckView Answer on Stackoverflow