MySQL Query pour créer un « bump-système » pour un forum que je fais
-
05-09-2019 - |
Question
Je ne parviens pas à former une requête MySQL qui exécute l'action suivante:
Sélectionner toutes les threadIDs de la commande de table de threads par l'horodatage (par ordre décroissant) du dernier message (le plus grand timestamp) avec ThreadID égal au ThreadID de chaque fil. Donc, fondamentalement, je veux aller à travers les fils et ont MySQL vérifier la base de données, disons fil 0. Il vérifie ensuite tous les postes qui ont ThreadID de 0 et thread0 sortes basées sur le plus grand horodatage des messages à l'intérieur de thread0. Ensuite, il répète cette opération pour thread1, thread2, etc et les trie en conséquence.
Est-ce même possible? Il est de créer l'effet du forum « bump-système », où fil le plus récemment actif est cogné au sommet de la liste continue jusqu'à ce que le fil meurt, il tombe au fond. Je l'habitude d'utiliser une implémentation différente où j'emmagasinés un horodatage de lastActivity dans le tableau des fils et mis à jour quand un nouveau poste a été présenté dans le filet, mais cette requête rendrait les choses beaucoup plus efficace.
Merci beaucoup! Il y a deux tables ici pertinentes: les discussions et les messages. Les postes ont un champ ThreadID qui stocke l'ID du fil il appartient, et il a également un champ d'horodatage. Sujets a une ThreadID de champ qui correspond à ThreadID du poteau.
La solution
Ce qui suit a travaillé pour moi dans le passé sur MySql. Si vous souhaitez inclure plus sur chaque fil dans la requête que vous devrez ajouter les colonnes à SELECT
et GROUP BY
.
select thread.threadID, max(comments.modifiedOn) as threadUpdated
from thread inner join comments on thread.threadID = comments.threadID
group by 1
order by 2 desc;
Cette requête sert votre demande principale, qui est une liste de fils commandé mon dernier commentaire. Il ne reviendra pas les discussions avec aucun commentaire en l'état, vous devez changer la jonction à une jointure externe pour le faire.
Autres conseils
SELECT *
FROM threads t
LEFT JOIN
posts p
ON p.id =
(
SELECT p.id
FROM posts pi
WHERE pi.threadID = t.threadID
ORDER BY
pi.timestamp DESC
LIMIT 1
)
Avoir un index sur posts (threadID, timestamp)
améliorera grandement cette requête.
Notez que contrairement aux solutions de GROUP BY
, cette requête sélectionne aussi tous les champs de posts
et fonctionne même si vous avez des doublons sur la dernière posts.timestamp
.
SELECT t.*, p1.`timestamp`
FROM threads t
JOIN posts p1 ON (p1.threadid = t.id)
LEFT JOIN posts p2 ON (p2.threadid = t.id
AND p1.`timestamp` < p2.`timestamp`)
WHERE p2.threadid IS NULL
ORDER BY p1.`timestamp` DESC;