MySQL group_concat问题

发布于 2024-10-09 15:55:07 字数 2059 浏览 5 评论 0原文

您好,

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

非常感谢对于如何解决这个问题有任何建议!

Greetings,

I have a very tricky problem with the group_concat function and I'm thinking for some days with no success, how to solve it.

There are 3 tables:

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

When all tasks need to be retrieved, with all tags that they are associated with as a result column, there is no problem with the following query:

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

The problem is when I need to select the tasks from one EXACT tag, but I still need to preserve the tags column with all of the tasks' associated tags. I try with the following query, but since the result is limited by WHERE tag_id = 5, the group_concat function retrieves just the tag with id = 5, e.g. "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   |
+---------+-----------+-------------+

The result that I'm trying to achieve is:

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

Thank you very much for any suggestions on how to resolve this!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诗酒趁年少 2024-10-16 15:55:07

您可以通过修改第一个查询以包含带有子查询的 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

You can do this by modifying your first query to include a where clause with a subquery:

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
予囚 2024-10-16 15:55:07

如果我理解您正在寻找的内容,我认为这会产生您想象的那种结果:

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

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

If I understand what you're looking for, I think this produces the sort of results you were imagining:

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

It starts with the first tag you were looking for, works its way back to the task associated with it, and then JOINs on all the tags for that task.

女皇必胜 2024-10-16 15:55:07

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

Use a HAVING instead of a WHERE, since a WHERE clause goes for every single row:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文