@izac

Many to many выборка новостей по тегам?

Доброе времени суток , есть 3 таблицы
news
id|text

tags
id|name

news_tags
id|tag_id|news_id

нужно собрать выбору новостей по тегам, основной тег + дополнительный тег , для примера, выбрать новости с тегом "животные" и "кроты", тег "кроты" может присутствовать так и нет (то есть все запись с тегом "животные" и , "животные" и "кроты" в паре) , есть решение через UNION но думаю оно здесь избыточно.

UPD наверно немного не верно задал вопрос , будет наверно понятней на примере
если мы задаём выборку по 2 тегам "животные" "кроты" должны быть новости
где тег только "животные", где теги парой "животные" "кроты", не подходят набор тегов в новостях как "животные" "коты" или "коты" "кроты"

выходит что то вроде такого , но думаю это не лучшее решение

SELECT news_id FROM news_tags WHERE tag_id = "id тега животное" OR tag_id = "id тега кроты" GROUP BY news_id HAVING COUNT(news_id) = 2; --находим пару животное кроты
UNION
SELECT news_id FROM news_tags WHERE tag_id = "id тега животное" AND news_id not in (SELECT news_id FROM news_tags WHERE tag_id in ("все теги в системе")); -- находим все новости с тегом животные и только ним больше у новости не может быть другого тега.
  • Вопрос задан
  • 119 просмотров
Пригласить эксперта
Ответы на вопрос 2
@hello_my_name_is_dany
Backend Developer (Node.js, PHP, C#)
Вы же понимаете, что по вашей логике дополнительный тег никакой роли не играет, потому что если в выборке нужны с "кротами" и без них, это просто все "животные". А если вам надо строго именно по двум тегам искать, то вот:
SELECT n.*
FROM news AS n
JOIN news_tags AS nt ON nt.news_id = n.id
JOIN tags AS t1 ON t1.id = nt.tag_id AND t1.name = "животные"
JOIN tags AS t2 ON t2.id = nt.tag_id AND t2.name = "кроты"


Вот ссылка на фидл с примером
www.sqlfiddle.com/#!9/70ce50/2/0
Ответ написан
@MaximaXXl
Нет смысла добавлять таблицу при каждом новом теге, можно через in и having
SELECT n.id, n.text
FROM news AS n
JOIN news_tags AS nt ON nt.news_id = n.id
JOIN tags AS t1 ON t1.id = nt.tag_id AND t1.name in ("животные", "кроты" /*перечисляете свои теги*/)
group by n.id, n.text
having count(distinct t1.id) = 2 /*кол-во перечисленных тегов*/
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы