使用 MySQL 在不同字段上的多个 GROUP_CONCAT

Posted

技术标签:

【中文标题】使用 MySQL 在不同字段上的多个 GROUP_CONCAT【英文标题】:Multiple GROUP_CONCAT on different fields using MySQL 【发布时间】:2011-11-22 08:00:33 【问题描述】:

我有一个这样的查询:

SELECT product.id,
       GROUP_CONCAT(image.id) AS images_id,
       GROUP_CONCAT(image.title) AS images_title,
       GROUP_CONCAT(facet.id) AS facets_id
...
GROUP BY product.id

查询有效,但不如预期,因为如果我有一个具有 5 个面和 1 个图像的产品(假设一个 id=7 的图像),那么我会在“images_id”中得到类似的内容:“7,7,7,7,7” 如果我有 2 张图片(7 和 3),那么我会得到类似:"7,7,7,7,7,3,3,3,3,3" 在方面我得到类似:"8,7,6,5,4,8,7,6,5,4"

我认为 mysql 正在对查询返回的不同行进行某种类型的联合,然后将所有内容连接起来。

我的预期结果是(最后一个例子):

images_id = "7,3" facets_id = "8,7,6,5,4"

我可以在 GROUP_CONCAT 中使用 DISTINCT 来获得它,但是我遇到了另一个问题: 如果我有两个具有相同标题的图像,其中一个被省略,然后我得到类似: images_id = "7,3,5" images_title = "Title7and3,Title5"

所以我错过了 images_id 和 images_title 之间的关系。

有人知道是否可以在 MySQL 中进行此查询吗?

也许我在没有任何实际好处的情况下使一切复杂化。 由于性能原因,我只尝试执行一个查询,但现在我不确定执行两个查询是否更快(例如一个用于选择构面,另一个用于图像)。

请说明您认为最好的解决方案是什么以及为什么。

谢谢!

【问题讨论】:

【参考方案1】:

只需添加DISTINCT

示例:GROUP_CONCAT(DISTINCT image.id) AS images_id

【讨论】:

我认为这需要扩展。 ' DISTINCT ' => GROUP_CONCAT(DISTINCT image.id) AS images_id 似乎不是 SQL 语法,MySQL 5.1 抛出语法错误。提问者没有提到任何编程语言,所以如果这个答案不是 SQL,则需要转换或解释。【参考方案2】:

您需要分别获取每个组:

SELECT
    p.id,
    images_id,
    images_title,
    facets_id,
    ...
FROM PRODUCT p
JOIN (SELECT product.id, GROUP_CONCAT(image.id) AS images_id
      FROM PRODUCT GROUP BY product.id) a on a.id = p.id
JOIN (SELECT product.id, GROUP_CONCAT(image.title) AS images_title
      FROM PRODUCT GROUP BY product.id) b on b.id = p.id
JOIN (SELECT product.id, GROUP_CONCAT(facet.id) AS facets_id
      FROM PRODUCT GROUP BY product.id) b on c.id = p.id
...

【讨论】:

我不太了解您的查询,但它看起来很复杂,我的意思是,我们需要为每个 concat 设置一个带有 group by 的子选择?看起来很慢,不是更快2个查询吗? @Enrique,这不是关于速度,而是关于正确性。如果我的代码不需要实际工作,我可以立即完成所有工作。 @Enrique,您不需要为每个组 concat 进行子选择,仅适用于与 p.id 匹配返回每个 p.id 超过 1 行的那些表。 好吧,我在我的问题中所说的,它是关于速度的,我试图在一个查询中选择所有内容,只是因为我想要表现出色。因为在不同的查询中选择我的所有数据对我来说要容易得多。但是 GROUP_CONCAT 变得如此困难,以至于我不确定我是否没有杀死 MySQL 而不是节省几毫秒。这就是我要求“最佳”解决方案的原因(以及您认为这是“最佳”解决方案的原因)。无论如何,我会测试你的查询,因为它真的很有趣,我从来没有做过这样的事情。 好吧,我无法调整您的查询来测试它,我的查询比我的问题中发布的要复杂得多。我将使用 2 查询解决方案。谢谢!【参考方案3】:

你可以只添加 DISTINCT 关键字,你会得到你想要的结果。

SELECT tb_mod.*, tb_van.*,
GROUP_CONCAT(DISTINCT tb_voil.vt_id) AS voil,
GROUP_CONCAT(DISTINCT tb_other.oa_id) AS other, 
GROUP_CONCAT(DISTINCT tb_ref.rp_id) AS referral
FROM cp_modules_record_tbl tb_mod 
LEFT JOIN cp_vane_police_tbl tb_van ON tb_van.mr_id= tb_mod.id
LEFT JOIN cp_mod_voilt_tbl tb_voil ON tb_voil.mr_id= tb_mod.id
LEFT JOIN cp_mod_otheraction_tbl tb_other ON tb_other.mr_id= tb_mod.id
LEFT JOIN cp_mod_referral_tbl tb_ref ON tb_ref.mr_id= tb_mod.id
WHERE tb_mod.mod_type = 2 GROUP BY tb_mod.id

【讨论】:

【参考方案4】:

如果问题是速度,那么简单地选择您需要的所有数据作为单独的行并在应用程序中进行分组可能会快得多,即:

SELECT product.id, image.id, image.title, facet.id

然后在应用程序中:

foreach row:
    push product_id onto list_of_product_ids
    push image_id onto list_of_image_ids
etc.

【讨论】:

以上是关于使用 MySQL 在不同字段上的多个 GROUP_CONCAT的主要内容,如果未能解决你的问题,请参考以下文章

mysql筛选GROUP BY多个字段组合时的用法分享

mysql 可以group by 两个字段吗

多个表上的mysql group_concat

GROUP_CONCAT 具有不同分隔符的多个字段

sqlserver2008,sql编程,group by 用法

sqlserver2008,sql编程,group by 用法