Masalah ini disebabkan oleh ekstensi khusus MySQL ke perilaku GROUP BY
ayat. Basis data lain akan membuat kesalahan... sesuatu yang mirip dengan agregat dalam daftar SELECT". (Kita bisa membuat MySQL membuat kesalahan serupa, jika kita menyertakan ONLY_FULL_GROUP_BY dalam sql_mode.)
Masalah dengan ekspresi messages.created
adalah yang mengacu pada nilai dari baris tak tentu di GROUP BY. Operasi ORDER BY terjadi lebih lama dalam pemrosesan, setelah operasi GROUP BY.
Untuk membuat "terbaru" untuk setiap grup, gunakan agregat ekspresi MAX(messages.created)
.
Untuk mendapatkan nilai lain dari baris yang sama, sedikit lebih rumit.
Dengan asumsi bahwa created
itu unik dalam conversation_id
yang diberikan grup (atau, jika tidak ada jaminan bahwa itu tidak unik, dan Anda boleh mengembalikan beberapa baris dengan nilai yang sama untuk created
...
Untuk mendapatkan created
terbaru untuk setiap conversation_id
SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
Anda dapat menggunakannya sebagai tampilan sebaris, untuk mendapatkan seluruh baris dengan created
terbaru itu
SELECT c.*
, m.*
FROM ( SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
) l
JOIN conversation c
ON c.id = l.conversation_id
JOIN messages m
ON m.conversation_id = l.conversation_id
AND m.created = l.created
WHERE (c.creator_id = :userId OR c.to_id = :userId)
CATATAN:
Anda dapat menambahkan ORDER BY
klausa untuk memesan baris yang dikembalikan sesuai kebutuhan.
WHERE
klausa pada kueri luar kemungkinan berlebihan, dan tidak perlu.
Kami lebih suka menghindari penggunaan SELECT *
, dan lebih memilih untuk secara eksplisit mencantumkan ekspresi yang akan dikembalikan.