1

问候,

我对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 的标签,例如“work”:

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  |
+---------+-----------+-------------+

非常感谢您提供有关如何解决此问题的任何建议!

4

3 回答 3

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
于 2010-12-27T18:24:58.160 回答
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

它从您要查找的第一个标签开始,返回与其关联的任务,然后加入该任务的所有标签。

于 2010-12-27T18:09:56.167 回答
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
于 2010-12-27T18:25:01.383 回答