Disons que j'ai une table appelée messages
avec les colonnes:
id | from_id | to_id | subject | message | timestamp
Je souhaite obtenir le dernier message de chaque utilisateur uniquement, comme vous le verriez dans votre boîte de réception FaceBook avant d'explorer le fil de discussion.
Cette requête semble me rapprocher du résultat dont j'ai besoin:
SELECT * FROM messages GROUP BY from_id
Cependant, la requête me donne le message le plus ancien de chaque utilisateur et non le plus récent.
Je ne peux pas comprendre celui-ci.
Vous devez trouver les dernières valeurs de timestamp
dans chaque groupe (sous-requête), puis joindre cette sous-requête à 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;
Essaye ça
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;
Il s'agit d'un problème standard.
Notez que MySQL vous permet d'omettre des colonnes de la clause GROUP BY, ce que Standard SQL ne fait pas, mais vous n'obtenez pas de résultats déterministes en général lorsque vous utilisez la fonction 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 le To_ID
pour correspondre à ce que vous êtes susceptible d'avoir. La requête fonctionnera sans elle, mais renverra beaucoup plus de données en général. La condition ne doit pas nécessairement être indiquée à la fois dans la requête imbriquée et dans la requête externe (l'optimiseur doit pousser la condition automatiquement), mais il ne peut pas nuire à répéter la condition comme indiqué.
Complétant simplement ce que Devart a dit, le code ci-dessous ne commande pas 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 nous devons d'abord réorganiser la "SOURCE" pour obtenir le "groupement" nécessaire:
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,