Instruction MySQL Select - Pour les messages
Question
Je dispose actuellement des tableaux suivants pour un forum de messagerie privée:
texte de remplacement http://img159.imageshack.us/img159/45/pmdata .jpg
texte de remplacement http://img504.yfrog.com/img504/3968/pminfo .jpg
Ce que j'essaie de faire, c'est de générer une " boîte de réception " affiche le fil de discussion le plus récent en haut et groupe par fil de discussion (vous ne voyez donc pas le même fil deux fois dans votre boîte de réception), quel que soit l'expéditeur.
Ce que j’ai actuellement fonctionne bien pour les messages simples entre deux uses. Cependant, une fois qu'un troisième utilisateur répond au même fil de discussion, il ne s'affiche pas correctement. Ma requête actuelle est la suivante:
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
INNER JOIN (SELECT thread_id, sender_id, MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id, sender_id) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent AND pm_data.sender_id = deriv1.sender_id
WHERE pm_info.receiver_id = '$usrID'
ORDER BY deriv1.thread_max_date_sent DESC
En supposant que $ usrID = 68 (par conséquent, receiver_id = 68), il génère ceci:
From: Kyle (pm_data.id = 18) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 12) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 8) RE: Test Number 2 (thread_id= 16256)
Notez que l'identifiant thread_id (13587) apparaît deux fois, car il y a 2 expéditeurs différents.
Comment pourrais-je l'avoir simplement pour afficher le dernier ID_filter, quel que soit l'expéditeur?
Merci beaucoup !!
La solution
Il semble en fait que la requête de la question initiale ne nécessite qu'un très petit changement pour obtenir l'enregistrement le plus récent pour chaque fil.
- déposez le sender_id dans les champs GROUP BY de la sous-requête
- supprimez pm_data.sender_id = dériv1.sender_id dans la clause ON
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent FROM pm_info INNER JOIN pm_data ON pm_info.message_id = pm_data.id INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID INNER JOIN (SELECT thread_id, /*sender_id,*/ MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id /*, sender_id*/) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent /*AND pm_data.sender_id = deriv1.sender_id*/ WHERE pm_info.receiver_id = '$usrID' ORDER BY deriv1.thread_max_date_sent DESC
Remarque: si possible, recherchez le messageID max dans cette sous-requête au lieu de max (date_sent)
Autres conseils
Essayez
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid
FROM pm_data, pm_info, tblUsers as sender
WHERE pm_info.message_id = pm_data.id
AND pm_data.sender_id = sender.usrID
AND pm_info.receiver_id = '$usrID'
GROUP BY thread_id
ORDER BY date_sent DESC
LIMIT 0,1
Essayez
SELECT pm_info.is_read, group_concat(DISTINCT sender.usrFirst) as sender_name,
pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid,
MAX(date_sent) AS thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
WHERE pm_info.receiver_id = '$usrID'
GROUP BY pm_data.thread_id
ORDER BY thread_max_date_sent DESC;
N'hésitez pas à être en désaccord avec la partie group_concat si elle ne répond pas à vos besoins. il ne fait que répertorier tous les expéditeurs pertinents au lieu de choisir un arbitraire.
Je vous conseillerais de scinder votre base de données en deux tables pour une meilleure normalisation: "thread". et "message". Il existe des informations de fil qui seraient communes à tous les messages, comme le titre du fil. Vous perdez de la place dans la table des messages en répétant les mêmes valeurs.
Vous pouvez avoir un "dernier temps de post" " champ la table de fil, qui est mise à jour à chaque nouvelle publication. Ensuite, il suffit simplement de sélectionner dans la table de discussion et de classer par le dernier message. Ce sera beaucoup plus rapide aussi.