Comment obtenir le dernier enregistrement dans chaque groupe en utilisant GROUP BY?
disons que j'ai une table appelée messages
avec les colonnes:
id | from_id | to_id | subject | message | timestamp
je veux obtenir le dernier message de chaque utilisateur seulement, comme vous verriez dans votre boîte de réception FaceBook avant de creuser dans le fil réel.
Cette requête semble me proche du résultat j'ai besoin:
SELECT * FROM messages GROUP BY from_id
Toutefois, la requête me donne le message le plus ancien de chaque utilisateur et pas le plus récent.
Je n'arrive pas à comprendre celui-ci.
6 réponses
Vous devriez trouver la dernière timestamp
valeurs dans chaque groupe (subquery), et puis joindre cette sousquery à la table -
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;
Essayez ceci
SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc
cette requête renvoie le dernier enregistrement pour chaque Form_id:
SELECT m1.*
FROM messages m1 LEFT JOIN messages m2
ON (m1.Form_id = m2.Form_id AND m1.id < m2.id)
WHERE m2.id IS NULL;
C'est un problème standard.
notez que MySQL vous permet d'omettre les colonnes du groupe par clause, ce que le SQL Standard ne fait pas, mais vous n'obtenez pas de résultats déterministes en général lorsque vous utilisez la facilité MySQL.
SELECT *
FROM Messages AS M
JOIN (SELECT To_ID, From_ID, MAX(TimeStamp) AS Most_Recent
FROM Messages
WHERE To_ID = 12345678
GROUP BY From_ID
) AS R
ON R.To_ID = M.To_ID AND R.From_ID = M.From_ID AND R.Most_Recent = M.TimeStamp
WHERE M.To_ID = 12345678
j'ai ajouté un filtre sur l' To_ID
correspond à ce que vous êtes susceptible d'avoir. La requête fonctionnera sans elle, mais retournera beaucoup plus de données en général. L'état ne devrait pas besoin d'être indiqués dans la requête imbriquée et l'extérieur requête (l'optimiseur doit pousser la condition automatique), mais il ne peut pas faire de mal de répéter l'état comme indiqué.
juste en complément de ce Qu'a dit Devart, le code ci-dessous n'est pas en ordre selon la question:
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;
la clause "GROUP BY" doit être dans la requête principale car il faut d'abord réordonner le "SOURCE" pour obtenir le "grouping" nécessaire ainsi:
SELECT t1.* FROM messages t1
JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages ORDER BY timestamp DESC) t2
ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp GROUP BY t2.timestamp;
Cordialement,
vous devez les commander.
SELECT * FROM messages GROUP BY from_id ORDER BY timestamp DESC LIMIT 1