【问题标题】:Grouping all query results into a single row将所有查询结果分组到一行
【发布时间】:2013-07-30 22:18:21
【问题描述】:

例如,我有一个带有标签的简单博客。我有一个 Blog 表、一个 Tag 表和一个 TagRelation 表。我想运行一个查询并在其自己的单行中获取每个博客文章的所有相关数据,包括标签。

SELECT Tag.id AS 'Tag.id', Tag.name AS 'Tag.name', Blog.id AS 'Blog.id', Blog.author AS 'Blog.author', Blog.title AS 'Blog.title', Blog.content AS 'Blog.content' 
FROM Blog 
INNER JOIN TagRelation ON TagRelation.target = Blog.id
INNER JOIN Tag ON Tag.id = TagRelation.Tag
WHERE Blog.id = '101'

这个查询将为每个标签提供一行,每个标签都有相同的博客帖子数据,帖子 ID 为 101,添加 GROUP BY Blog.id 只会给我一行,但任意第一个标签结果是什么。

我想要的是这样的:

Blog.id | Blog.author | Blog.title | Blog.content | Tag.id | Tag.name | Tag.id | Tag.name 
-----------------------------------------------------------------------------------------
101     | someone     | something  | lolstuff     | 1      | tag1     | 2      | tag2

这样我的客户端代码就可以轻松地将其解析为对象。这在 MySQL 中是否可行,无需为同一个博客 ID 处理多个匹配行,或者只为获取每个帖子的标签而进行子查询? (实际的数据库当然比这个更大更复杂,我想尽可能多地做join。)

【问题讨论】:

  • 在一般情况下你不能这样做(假设一篇给定的博客文章有任意数量的标签)。但是在应用程序代码中迭代列而不是行真的更容易吗?

标签: mysql join group-by


【解决方案1】:

一个涉及使用GROUP_CONCAT()的解决方案:

SELECT
    GROUP_CONCAT(Tag.id SEPARATOR ',') AS 'Tag.ids',
    GROUP_CONCAT(Tag.name SEPARATOR ',') AS 'Tag.names',
    Blog.id, Blog.author, Blog.title, Blog.content
FROM Blog 
INNER JOIN TagRelation ON TagRelation.target = Blog.id
INNER JOIN Tag ON Tag.id = TagRelation.Tag
WHERE Blog.id = '101'
GROUP BY Blog.id

这会在Tag.idsTag.names 列中分别生成对应Tag.idTag.name 的两个逗号分隔列表。

但同样,在应用程序代码中迭代列(或在这种情况下为逗号分隔的值)而不是行真的更容易吗?

【讨论】:

  • 我忘了在我的帖子中提到这一点。你是对的,我可以用 group_concat 完成它,遍历字符串,或者为每个博客文章运行第二个查询以获取标签并遍历它,但我在这里寻找更聪明/优雅/更快的解决方案.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多