これが私の単純化されたメッセージ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
このクエリから、すべての相手との最後のメッセージのリストを取得しました。ここで、最後のメッセージが FROM collocutor から ME であったすべての collocutors で、すべての最後のメッセージ ID を取得する必要があります。最初のアイデアは、メッセージ テーブルを 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 エラーが起きます。2 番目のアイデアは、「うーん、実際には 2 番目のメッセージ テーブルを最初のクエリの結果に結合する必要がある」というものでした。そのため、モンキー コードが誕生しました。
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}
それで、それは働いています。しかし、最適化についてはどうですか?アイデアはありますか?