проблемы с использованием GROUP_CONCAT в MYSQL

у меня есть следующие таблицы:

сообщения: идентификатор, заголовок, дата, содержание

теги: идентификатор, имя

posts_tags: post_id, tag_id

Я хочу выделить заголовок со списком связанных тегов; следующий запрос отлично работает

SELECT p.title, GROUP_CONCAT( t.name ORDER BY t.name SEPARATOR ',' ) as tags_list
FROM posts AS p
JOIN posts_tags AS pt ON pt.post_id = p.id
JOIN tags AS t ON pt.tag_id = t.id
GROUP BY p.id

с этим запросом я получаю что-то похожее на это

title             |  tags_list
==================|===============================
Old cinema        |  film,movies
cooking shows     |  cooking,food,kitchen,television
Epic War Films    |  history,movies,war
Art in France     |  art,france,history

когда я хочу публиковать только сообщения с определенным тегом (например, "фильмы"), я попытался добавить предложение where:

SELECT p.title, GROUP_CONCAT( t.name ORDER BY t.name SEPARATOR ',' ) as tags_list
FROM posts AS p
JOIN posts_tags AS pt ON pt.post_id = p.id
JOIN tags AS t ON pt.tag_id = t.id
WHERE t.name = 'movies'
GROUP BY p.id

я заканчиваю с этим

title            |  tags_list
=================|===============================
Old cinema       |  movies
Epic War Films   |  movies

Я получил все сообщения с тегами "фильмы", но проблема в том, что столбец "tag_list" показывает только "фильмы" в каждой строке, вместо того, чтобы включать все другие теги, связанные с сообщением.

Как я могу это исправить?


person cardflopper    schedule 06.06.2013    source источник


Ответы (2)


Условие нужно ставить на результат GROUP_CONCAT, а не на каждую строку, так как @AshwinMukhija предположил, что условие должно быть в предложении HAVING:

SELECT 
    p.title, 
    GROUP_CONCAT( t.name ORDER BY t.name SEPARATOR ',' ) as tags_list
FROM 
    posts AS p
JOIN posts_tags AS pt 
    ON pt.post_id = p.id
JOIN tags AS t 
    ON pt.tag_id = t.id
GROUP BY 
    p.id
HAVING
    FIND_IN_SET('movies',tags_list)

FIND_IN_SET возвращает истину, если строка movies находится в списке, разделенном запятыми tags_list

person Stephan    schedule 06.06.2013
comment
спасибо Стефан, отлично работает. Я думаю, что у Эшвина была правильная идея, но использование FIND_IN_SET сработало для меня. - person cardflopper; 06.06.2013

Вам просто нужно сместить условие в вашем теге с предложения where на having

SELECT p.title, GROUP_CONCAT( t.name ORDER BY t.name SEPARATOR ',' ) as tags_list
FROM posts AS p
JOIN posts_tags AS pt ON pt.post_id = p.id
JOIN tags AS t ON pt.tag_id = t.id
GROUP BY p.id
HAVING t.name = 'movies'
person Achrome    schedule 06.06.2013
comment
Привет, Эшвин, когда я использую этот запрос, я получаю сообщение об ошибке: # 1054 - Неизвестный столбец 't.name' в 'имеющем предложении' - person cardflopper; 06.06.2013