SQL → Выборка постов с определёнными тегами

21.07.2011

Есть таблицы posts(id, title, text) и tags(id, name), связанные отношением многие-ко-многим с помощью таблицы posts_tags(post_id, tag_id).

Задача — выбрать посты с определёнными тегами.

Вариант 1:

SELECT p.id, p.title, p.text
FROM posts p
INNER JOIN posts_tags pt1 ON pt1.post_id = p.id
INNER JOIN posts_tags pt2 ON pt2.post_id = p.id
WHERE
    pt1.tag_id = ID_ПЕРВОГО_ТЕГА AND
    pt2.tag_id = ID_ВТОРОГО_ТЕГА

Таблица posts_tags джойнится столько раз, сколько тегов участвует в выборке (в примере их два).

Вариант 2:

SELECT p.id, p.title, p.text
FROM posts p
WHERE p.id IN (
    SELECT pt.post_id
    FROM posts_tags pt
    INNER JOIN posts_tags pt1 ON pt.post_id = pt1.post_id AND pt1.tag_id = ID_ПЕРВОГО_ТЕГА
    INNER JOIN posts_tags pt2 ON pt.post_id = pt2.post_id AND pt2.tag_id = ID_ВТОРОГО_ТЕГА
)

Таким способом делает выборку модуль Views в Drupal.

Вариант 3:

SELECT p.id, p.title, p.text
FROM posts p
INNER JOIN posts_tags pt ON pt.post_id = p.id
WHERE pt.tag_id IN (ID_ПЕРВОГО_ТЕГА, ID_ВТОРОГО_ТЕГА)
GROUP BY p.id
HAVING COUNT(*) >= 2

В HAVING указывается количество тегов участвующих в выборке (в примере их два). Таким способом делает выборку модуль Search в Drupal.

Похожие записи

Комментарии

Как вариант:

select
p.id,
p.title,
p.text,
p.tag_ids
from (
	select 
	posts.id,
	posts.title,
	posts.text,
	group_concat(posts_tags.tag_id) tag_ids
	from posts
	left join posts_tags on posts_tags.post_id = posts.id
	group by posts.id
) p
where 
find_in_set(<id-тега1>, p.tag_ids) and find_in_set(<id-тега2>, p.tag_ids) ...

Добавить комментарий