I'm programming a private conversation system and need advices on my most complex request.
My (simplified) tables, under MySQL 5.5 :
user:
id (int)
username (string)
conversation:
id (int)
subject (string)
conversation_user:
conversation_id (int)
user_id (int)
message:
id (int)
conversation_id (int)
user_id (int)
content (text)
created_at (datetime)
So, I want to display to the user the list of the conversations in which he is participating : for each conversation, I need the conversation id, the conversation subject, the list of participating users, the last message id, the last message author id and username, and the last message date.
I've written this request, which looks pretty bad :
SELECT
cu.conversation_id,
c.subject,
u.username,
m.id,
m.user_id,
m.created_at
FROM conversation_user cu
JOIN conversation c ON c.id = cu.conversation_id
JOIN conversation_user cu2 ON cu2.conversation_id = c.conversation_id
JOIN user u ON u.id = cu2.user_id
JOIN message m ON m.conversation_id = cu.conversation_id
WHERE cu.user_id = :current_user_id # the session user_id
AND m.id = (SELECT MAX(id) FROM message WHERE conversation_id = cu.conversation_id)
So, I would like to know if you guys see a better way to get the same result ?
I've already read GROUP BY behavior when no aggregate functions are present in the SELECT clause, that's why I didn't put a GROUP BY clause and wrote the last line instead :
AND m.id = (SELECT MAX(id) FROM message WHERE conversation_id = cu.conversation_id)
Thanks !
Edit
I did an EXPLAIN on this request, and there is no KEY used for the JOIN user u ON u.id = cu2.user_id
line : why ?
(the first question is still relevant)