这是我的简单消息数据库
id | from_id | to_id | created_at
所以我有查询来获取对话框列表(这里我只从结果中获取 coll - 最后一条消息的最后一个 id 与 collocutor):
SELECT IF(to_id = #{id}, from_id, to_id) as coll,
LEAST(from_id,to_id),
GREATEST(from_id, to_id),
MAX(created_at),
MAX(id) FROM `messages`
WHERE LEAST(from_id,to_id) = #{id} or GREATEST(from_id, to_id) = #{id}
GROUP BY LEAST(from_id,to_id), GREATEST(from_id, to_id)
ORDER BY MAX(created_at) DESC
从这个查询中,我得到了每个合作者的最后一条消息的列表。现在我需要获取所有最后一条消息的 id 与每个 colocutors 的最后一条消息是从 collocutor 到我的。第一个想法是通过 MAX(id) 加入消息表。于是代码诞生了:
SELECT IF( m1.to_id = #{id}, m1.from_id, m1.to_id ) AS coll,
LEAST( m1.from_id, m1.to_id ) ,
GREATEST( m1.from_id, m1.to_id ) ,
MAX( m1.created_at ) ,
MAX( m1.id )
FROM `messages` AS m1
INNER JOIN messages AS m2 on m2.id = MAX( m1.id )
WHERE (
LEAST( m1.from_id, m1.to_id ) = #{id}
OR GREATEST( m1.from_id, m1.to_id ) = #{id}
)
AND
m2.from <> #{id}
GROUP BY LEAST( m1.from_id, m1.to_id ) , GREATEST( m1.from_id, m1.to_id )
ORDER BY MAX( m1.created_at ) DESC
但是是上升#1111 错误。第二个想法是“嗯,实际上我需要将第二个消息表加入到第一个查询的结果中”。所以现在诞生了猴子代码:
Select * from (SELECT IF(to_id = #{id}, from_id, to_id) as coll,
LEAST(from_id,to_id),
GREATEST(from_id, to_id),
MAX(created_at),
MAX(id) as max_id
FROM `messages`
WHERE LEAST(from_id,to_id) = #{id} or GREATEST(from_id, to_id) = #{id}
GROUP BY LEAST(from_id,to_id), GREATEST(from_id, to_id)
ORDER BY MAX(created_at) DESC) m1
LEFT JOIN messages as m2 on m1.max_id = m2.id
WHERE to_id =#{id}
所以,这行得通。但是优化呢?有什么想法吗?