group_concat 在多个连接上工作不正确

Posted

技术标签:

【中文标题】group_concat 在多个连接上工作不正确【英文标题】:group_concat works incorrect on multiple join 【发布时间】:2021-04-03 00:08:40 【问题描述】:

我在使用来自 3 个表的连接和连接数据构建选择请求时遇到问题。

第一个表 entity 有一些实体的 ID 及其作者:

id author
11 "John"
12 "Mike"
13 "Kevin"

第 2 和第 3 表包含与此实体相关的部分和文件,每行占一行。任何实体的节数和文件数都可以不同。

文件

id entity_id file_name
1 11 file1
2 12 file1
3 12 file2
4 12 file3
5 13 file4
6 13 file5
7 13 file6

section(在这个例子中,有些实体也可以是没有部分的,比如 12):

id entity_id section_id
1 11 1001
2 11 1002
3 13 1003

我需要从连接相关部分和文件的实体表中选择所有数据作为逗号分隔的字符串。为此,我创建了以下请求:

SELECT 
    entity.id, 
    entity.author, 
    group_concat(section.section_id) section_ids, 
    group_concat(file.file_name) files 
FROM entity
LEFT JOIN file ON entity.id = file.entity_id
LEFT JOIN section ON entity.id = section.entity_id
group by entity.id;

我希望得到以下结果:

id author files section_ids
11 "John" file1 1001,1002
12 "Mike" file1,file2,file3 null
13 "Kevin" file4,file5,file6 1003

但实际上我得到了这个:

id author files section_ids
11 "John" file1,file1 1001,1002
12 "Mike" file1,file2,file3 null
13 "Kevin" file4,file5,file6 1003,1003,1003

看起来文件在实体有多个部分时重复,而在实体有多个文件时部分重复。 我尝试使用不同类型的连接(内/外,右/左),但没有找到任何解决方案。请帮我解决这个问题。

【问题讨论】:

【参考方案1】:

您要结合两个不同的维度,从而得到笛卡尔积。对查询最简单的调整是 DISTINCT:

SELECT e.id, e.author, 
      group_concat(distinct s.section_id) as section_ids, 
      group_concat(f.file_name) as files 
FROM entity e LEFT JOIN
     file f
     ON e.id = f.entity_id LEFT JOIN
     section s
     ON e.id = s.entity_id
group by e.id;

但是,为了性能,我会推荐 GMB 建议的方法。

【讨论】:

所以您打开了我关闭为重复的问题并将重复链接的答案作为您的答案发布:***.com/questions/3083499/… ? 我对您的答案投了反对票,因为它与重复链接中的答案完全相同,为了发布它,您打开了一个封闭的问题,尽管您知道该问题是重复的。【参考方案2】:

问题是当您在给定实体的两个表中都有多个匹配项时:连接乘以行,并且聚合的结果是错误的。

我建议预先聚合。几个子查询应该可以很好地完成工作:

select e.id, e.author, 
    (select group_concat(f.file_name) from file f where f.entity_id = e.id) as files_names
    (select group_concat(s.section_id) from section s where s.entity_id = e.id) as section_ids
from entity e

【讨论】:

以上是关于group_concat 在多个连接上工作不正确的主要内容,如果未能解决你的问题,请参考以下文章

Windows-Service 在 net.tcp 连接上失败,但控制台应用程序工作正常

MySQL 使用 GROUP_CONCAT 和多个 JOINS

Socket.IO 客户端在 3g/4g 连接上无法正常工作

我可以在一个连接上有多个“类别”吗?

在 JSON-RPC 连接上读取多个 JSON 对象

多个(级联)左连接上的 Linq 查询 NullReferenceException