Problém je způsoben rozšířením chování GROUP BY
specifické pro MySQL doložka. Jiné databáze by vyvolaly chybu... něco podobného on-aggregate v seznamu SELECT." (Můžeme přimět MySQL, aby vyvolalo podobnou chybu, pokud do sql_mode zahrneme ONLY_FULL_GROUP_BY.)
Problém s výrazem messages.created
je to, že odkazuje na hodnotu z neurčitého řádku v GROUP BY. Operace ORDER BY nastává mnohem později ve zpracování, po operaci GROUP BY.
Chcete-li získat „nejnovější“ vytvořené pro každou skupinu, použijte agregát výraz MAX(messages.created)
.
Získání ostatních hodnot ze stejného řádku je trochu složitější.
Za předpokladu, že created
je jedinečný v rámci daného conversation_id
skupina (nebo, pokud není zaručeno, že není jedinečná, a můžete vracet více řádků se stejnou hodnotou pro created
...
Chcete-li získat nejnovější created
pro každý 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
Můžete to použít jako vložené zobrazení, abyste získali celý řádek s nejnovějším created
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)
POZNÁMKY:
Můžete přidat ORDER BY
klauzule, aby se řádky vrátily, jakkoli potřebujete.
WHERE
klauzule na vnějším dotazu je pravděpodobně nadbytečná a zbytečná.
Raději se vyvarujeme použití SELECT *
a preferujete explicitní výpis výrazů, které mají být vráceny.