问候,
我对 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 |
+---------+-----------+-------------+
非常感谢您就如何解决此问题提出任何建议!
答案 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