Първо, моля да ме извините, че промених малко имената на таблиците на message
и message_tag
за четливост.
Второ, не съм тествал това. Използвайте го по-скоро като указател, отколкото като категоричен отговор.
Заявката използва две подзаявки, които може да не са толкова ефективни, вероятно има място за подобрение. Първо, най-вътрешната заявка търси етикетите на текущото съобщение. След това средната заявка търси съобщения, които са маркирани с поне един общ етикет. Групирането се използва за получаване на уникален message_id и подреждането им по брой общи тагове. Последно, JOIN
се използва за зареждане на допълнителни подробности и за филтриране на старите съобщения.
Може да забележите, че използвах въпросителни знаци вместо '$xyz'
. Това е, за да се избегне грижата за избягване на съдържанието на променливата.
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 < ?