Reputation: 709
I have this code:
SELECT a.id, a.to_id, a.from_id, a.seen, a.date, a.message
FROM `Chat_messages` a
INNER JOIN (
SELECT MAX( `id` ) AS id
FROM `Chat_messages` AS `alt`
WHERE `alt`.`to_id` =7
OR `alt`.`from_id` =7
GROUP BY `to_id` , `from_id`
)b ON a.id = b.id
returning:
So, I want to get conversations (sent and received messages) of an user and latest message of it. Latest message works ok, but the problem is that I get 2 rows from messages received (#1 and #2) and 2 rows from messages sent (#3 and #4), but I only need 2 results, because there are 2 conversations.
Upvotes: 1
Views: 1153
Reputation: 395
The best way to pick out the row that holds the latest sent message and the row that holds the latest received message respectively, is using the row_number() window function. Unfortunately, MySql does not support window functions, so I think it's best to use two nested SELECT's:
SELECT z.id, max(z.to_id), max(z.from_id), max(z.seen), max(z.date), max(z.message)
FROM chat_messages z
LEFT JOIN
(SELECT x.from_id, max(date) date
FROM chat_messages x
GROUP BY x.from_id) f
ON z.from_id = f.from_id AND z.date = f.date
LEFT JOIN
(SELECT y.to_id, max(date) date
FROM chat_messages y
GROUP BY y.to_id) t
ON z.to_id = t.to_id AND z.date = t.date
GROUP BY z.id
I do not recommend using max on ID's if you care about correctness in the long run.
Upvotes: 3
Reputation: 12772
You can group by least(to_id, from_id), greatest(to_id, from_id)
to make sure conversions between 2 people are merged:
SELECT a.id, a.to_id, a.from_id, a.seen, a.date, a.message
FROM `Chat_messages` a
INNER JOIN (
SELECT MAX( `id` ) AS id
FROM `Chat_messages` AS `alt`
WHERE `alt`.`to_id` =7
OR `alt`.`from_id` =7
GROUP BY least(`to_id` , `from_id`), greatest(`to_id` , `from_id`)
)b ON a.id = b.id
Upvotes: 2