MySQL group_concat问题

时间:2010-12-27 17:58:05

标签: mysql group-concat

问候,

我对 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 个答案:

答案 0 :(得分:2)

您可以通过修改第一个查询以包含带子查询的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 :(得分:1)

如果我理解你在寻找什么,我认为这会产生你想象的那种结果:

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

它从你正在寻找的第一个标签开始,回到与之相关的任务,然后加入该任务的所有标签。

答案 2 :(得分:1)

使用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