Przede wszystkim wybacz, że zmieniłem nieco nazwy tabel na message
i message_tag
dla czytelności.
Po drugie, nie testowałem tego. Użyj go raczej jako wskaźnika niż ostatecznej odpowiedzi.
Zapytanie wykorzystuje dwa podzapytania, które mogą nie być tak wydajne, że prawdopodobnie jest miejsce na ulepszenia. Najpierw najgłębsze zapytanie szuka tagów bieżącej wiadomości. Następnie środkowe zapytanie wyszukuje wiadomości, które są oznaczone co najmniej jednym wspólnym tagiem. Grupowanie służy do uzyskania unikalnego identyfikatora wiadomości i uporządkowania ich według liczby wspólnych tagów. Na koniec JOIN
służy do ładowania dodatkowych szczegółów i odfiltrowywania starych wiadomości.
Możesz zauważyć, że użyłem znaków zapytania zamiast '$xyz'
. Ma to na celu uniknięcie troski o ucieczkę zawartości zmiennej.
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 < ?