Allereerst, excuseer me dat ik de tabelnamen een beetje heb gewijzigd in message
en message_tag
voor leesbaarheid.
Ten tweede heb ik dit niet getest. Gebruik het eerder als een aanwijzing dan als een definitief antwoord.
De query gebruikt twee subquery's, die misschien niet zo efficiënt zijn, er is waarschijnlijk ruimte voor verbetering. Eerst zoekt de binnenste query naar de tags van het huidige bericht. Vervolgens zoekt de middelste zoekopdracht naar berichten die zijn gemarkeerd met ten minste één gemeenschappelijke tag. De groepering wordt gebruikt om een unieke message_id te krijgen en deze te ordenen op aantal gemeenschappelijke tags. Als laatste, de JOIN
wordt gebruikt om extra details te laden en om de oude berichten eruit te filteren.
Het is je misschien opgevallen dat ik vraagtekens heb gebruikt in plaats van '$xyz'
. Dit is om de zorg over het ontsnappen van de variabele inhoud te vermijden.
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 < ?