Em primeiro lugar, desculpem-me por alterar um pouco os nomes das tabelas para
message
e message_tag
para legibilidade. Segundo, eu não testei isso. Use-o mais como um ponteiro do que como uma resposta definitiva.
A consulta usa duas subconsultas, que podem não ser tão eficientes, provavelmente há espaço para melhorias. Primeiro, a consulta mais interna procura as tags da mensagem atual. Em seguida, a consulta do meio procura mensagens marcadas com pelo menos uma tag comum. O agrupamento é usado para obter o message_id exclusivo e ordená-los pelo número de tags comuns. Por último, o
JOIN
é usado para carregar detalhes adicionais e filtrar as mensagens antigas. Você pode notar que usei pontos de interrogação em vez de
'$xyz'
. Isso é para evitar o cuidado de escapar do conteúdo da variável. 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 < ?