Я программирую систему частных бесед и нуждаюсь в советах по моему сложному запросу.
Мои (упрощенные) таблицы под 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)
Итак, я хочу отобразить пользователю список разговоров, в которых он участвует: для каждого разговора мне нужен идентификатор разговора, тема разговора, список участвующих пользователей, идентификатор последнего сообщения, последнее идентификатор автора сообщения, имя пользователя и дата последнего сообщения.
Я написал этот запрос, который выглядит довольно плохо:
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)
Итак, я хотел бы знать, видите ли вы, ребята, лучший способ получить тот же результат?
Я уже прочитал поведение GROUP BY, когда в предложении SELECT нет агрегатных функций , поэтому я не поместил предложение GROUP BY и вместо этого написал последнюю строку:
AND m.id = (SELECT MAX(id) FROM message WHERE conversation_id = cu.conversation_id)
Спасибо!
Редактировать
Я сделал EXPLAIN по этому запросу, и для строки JOIN user u ON u.id = cu2.user_id
не используется KEY: почему?
(первый вопрос все еще актуален)