这是我的简单消息DB
id | from_id | to_id | created_at
所以我有查询获取对话框列表(这里我只得到结果的coll - 最后一条带有collocutor的消息的最后一个id):
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
从这个查询中我得到了每个collocutors的最后消息列表。现在我需要获得所有最后的消息id与每个collocutors,其中最后一条消息是从collocutor到ME。第一个想法是通过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}
所以,那是有效的。但是优化呢?有任何想法吗?