MySQL group_concat проблема - PullRequest
       5

MySQL group_concat проблема

1 голос
/ 27 декабря 2010

Привет,

У меня очень сложная проблема с функцией group_concat , и я несколько дней безуспешно думаю, как ее решить.

Есть 3 таблицы:

tasks                    task_tag                 tag      
+---------+----------+   +---------+----------+   +---------+----------+
| task_id |   data   |   | task_id |  tag_id  |   | tag_id  |   name   |
+---------+----------+   +---------+----------+   +---------+----------+
|       1 | task 1   |   |    1    |    5     |   |    5    |   work   |
|       2 | task 2   |   |    1    |    7     |   |    6    |  school  |
|       3 | task 3   |   |    2    |    6     |   |    7    |   home   |
+---------+----------+   +---------+----------+   +---------+----------+

Когда необходимо получить все задачи со всеми тегами, с которыми они связаны в столбце результата, проблем со следующим запросом не возникает:

SELECT t.task_id, t.data, GROUP_CONCAT(tg.name) AS tags
FROM tasks t
LEFT JOIN task_tag tt ON tt.task_id = t.task_id
LEFT JOIN tag tg ON tg.tag_id = tt.tag_id
GROUP BY t.task_id

result
+---------+-----------+-------------+
| task_id |  data     |   tags      |
+---------+-----------+-------------+
|    1    |  task 1   |  work,home  |
|    2    |  task 2   |  school     |
|    3    |  task 3   |  NULL       |
+---------+-----------+-------------+

Проблема в том, что мне нужно выбрать задачи из одного тега EXACT, но мне все равно нужно сохранить столбец тегов со всеми тегами, связанными с задачами. Я пытаюсь выполнить следующий запрос, но так как результат ограничен WHERE tag_id = 5, функция group_concat извлекает только тег с id = 5, например, "Работа":

SELECT t.task_id, t.data, GROUP_CONCAT(tg.name) AS tags
FROM tasks t
LEFT JOIN task_tag tt ON tt.task_id = t.task_id
LEFT JOIN tag tg ON tg.tag_id = tt.tag_id
WHERE tg.tag_id = 5
GROUP BY t.task_id

result
+---------+-----------+-------------+   
| task_id |   data    |      tags   |
+---------+-----------+-------------+
|    1    |  task 1   |      work   |
+---------+-----------+-------------+

Результат, которого я пытаюсь достичь:

result
+---------+-----------+-------------+   
| task_id |  data     |     tags    |
+---------+-----------+-------------+
|    1    |  task 1   |  work,home  |
+---------+-----------+-------------+

Большое спасибо за любые предложения по решению этой проблемы!

Ответы [ 3 ]

2 голосов
/ 27 декабря 2010

Вы можете сделать это, изменив свой первый запрос, включив в него предложение where с подзапросом:

SELECT t.task_id, t.data, GROUP_CONCAT(tg.name) AS tags
FROM tasks t
LEFT JOIN task_tag tt ON tt.task_id = t.task_id
LEFT JOIN tag tg ON tg.tag_id = tt.tag_id
WHERE t.task_id IN (SELECT task_id FROM task_tags WHERE tag_id=5)
GROUP BY t.task_id
1 голос
/ 27 декабря 2010

Используйте HAVING вместо WHERE, поскольку предложение WHERE относится к каждой отдельной строке:

SELECT t.task_id, t.data, GROUP_CONCAT(tg.name) AS tags
FROM tasks t
LEFT JOIN task_tag tt ON tt.task_id = t.task_id
LEFT JOIN tag tg ON tg.tag_id = tt.tag_id
GROUP BY t.task_id
HAVING Count(IF(tg.tag_id = 5,1,NULL)) > 0
1 голос
/ 27 декабря 2010

Если я понимаю, что вы ищете, я думаю, что это дает результаты, которые вы представляли:

SELECT tasks.task_id, tasks.data, GROUP_CONCAT(tag.name) AS tags
FROM tag AS looking_for
JOIN task_tag AS first_tt ON first_tt.tag_id = looking_for.tag_id
JOIN tasks ON tasks.task_id = task_tag.task_id
JOIN task_tag AS second_tt ON second_tt.task_id = tasks.task_id
JOIN tag ON tag.tag_id = second_tt.tag_id
WHERE looking_for.tag_id = 5
GROUP BY tasks.task_id

Он начинается с первого тега, который вы искали, возвращается кзадача, связанная с ней, а затем присоединяется ко всем тегам для этой задачи.

...