Tout d'abord, excusez-moi d'avoir un peu changé les noms des tables en message
et message_tag
pour la lisibilité.
Deuxièmement, je n'ai pas testé cela. Utilisez-le plutôt comme un pointeur que comme une réponse définitive.
La requête utilise deux sous-requêtes, qui pourraient ne pas être aussi efficaces, il y a probablement place à l'amélioration. Tout d'abord, la requête la plus interne recherche les balises du message actuel. Ensuite, la requête du milieu recherche les messages qui sont marqués avec au moins une balise commune. Le regroupement est utilisé pour obtenir un message_id unique et les classer par nombre de balises communes. Enfin, le JOIN
est utilisé pour charger des détails supplémentaires et filtrer les anciens messages.
Vous remarquerez peut-être que j'ai utilisé des points d'interrogation au lieu de '$xyz'
. Ceci afin d'éviter le souci d'échapper au contenu de la variable.
SELECT message_id, title, date
FROM message
RIGHT JOIN (SELECT message_id, COUNT(*)
FROM message_tag
WHERE tag_id IN
(SELECT MT.tag_id FROM message_tag MT WHERE MT.message_id = ?)
GROUP BY message_id
ORDER BY COUNT(*) DESC) RELATED_MESSAGES
ON message.message_id = RELATED_MESSAGES.message_id
WHERE date < ?