В этом блоге примерно с середины 2007-го, когда я переписал его с файлового велосипедохранилища на нормальный SQL, появилась возможность выбрать посты, содержащие все заданные теги. В 2008-м возможность окончательно оформилась в теговую навигацию.
Изначальный способ выборки, который используется и сейчас:
SELECT * FROM post p JOIN post_tag pt1 ON pt1.post_id = p.id JOIN tag t1 ON t1.id = pt1.tag_id AND t1.name = 'php' JOIN post_tag pt2 ON pt2.post_id = p.id JOIN tag t2 ON t2.id = pt2.tag_id AND t2.name = 'yii' -- для каждого дополнительного тега добавляем ещё JOIN-ы
Недавно Максим подсказал способ поизвращённее:
-- Сначала выбираем посты с тегом yii и посты с тегом php -- через IN. Если у поста и тот и тот тег, он будет выбран -- несколько раз. SELECT * FROM post p JOIN post_tag pt ON pt.post_id = p.id JOIN tag t ON pt.tag_id = t.id WHERE t.name IN ('php', 'yii') -- Считаем количество раз, которые выбрался пост. Если оно -- совпадает с количеством тегов в нашем списке, то это -- означает, что у поста есть и тот и тот тег. GROUP BY p.id HAVING COUNT(pt.tag_id) = 2
Есть ли ещё интересные способы решения этой задачи?