首页 > 解决方案 > 将非空 CONCAT_GROUP 连接到 MySQL 中的父列

问题描述

我需要从 store_cat 中获取类别列表,COUNT从 store_item (产品数量)和GROUP_CONCATstore_cat_attributes (属性列表)中获取子项。问题是,使用CONCAT函数我需要将GROUP_CONCAT值附加name到父表(store_cat)中的列,这就是它变得棘手的地方。

这工作正常:

SELECT
    store_cat.id_cat AS id,
    store_cat.name AS name,
    GROUP_CONCAT(store_cat_attribute.name SEPARATOR ", ") AS attributes,
    COUNT(store_item.id_item) AS products,
    store_cat.flg_public AS flg_public
FROM store_cat
LEFT JOIN store_item ON store_item.id_cat = store_cat.id_cat
LEFT JOIN store_cat_attribute ON store_cat_attribute.id_cat = store_cat.id_cat
WHERE store_cat.id_store = 1
GROUP BY store_cat.id_cat
ORDER BY name

但这是我真正需要的。问题是,当我执行此查询时,store_cat.name 值在没有属性时显示为空值:

SELECT
    store_cat.id_cat AS id,
    CONCAT(store_cat.name, " (", GROUP_CONCAT(store_cat_attribute.name SEPARATOR ", "), ")") AS name,
    COUNT(store_item.id_item) AS products,
    store_cat.flg_public AS flg_public
FROM store_cat
LEFT JOIN store_item ON store_item.id_cat = store_cat.id_cat
LEFT JOIN store_cat_attribute ON store_cat_attribute.id_cat = store_cat.id_cat
WHERE store_cat.id_store = 1
GROUP BY store_cat.id_cat ORDER BY name

基本上,这个想法是该store_cat.name列应该包含带有CONCATand的属性列表GROUP_CONCAT,就像这样:

这是当前的SQLfiddle。顺便说一句,当前GROUP_CONCAT. 它显示的是 ( XL , S, M, L) 而不是 (S, M, L, XL )。

要解决的问题:

  1. GROUP_CONCAT仅当有属性时才用于将属性连接到类别名称。

  2. 使用store_cat_attributes.position设置GROUP_CONCAT值的顺序。

有任何想法吗?谢谢!

标签: mysqlsqlconcatgroup-concat

解决方案


以下表达式应返回您期望的结果:

CONCAT(
    store_cat.name,
    IFNULL(
        CONCAT(
            ' (', 
            GROUP_CONCAT(
                store_cat_attribute.name 
                ORDER BY store_cat_attribute.position 
                SEPARATOR ', '
             ),
            ')'
        ),
        ''
    )
) AS name

基本上,这只是尝试GROUP_CONCAT()属性,如果结果是,NULL那么它将属性列表转换为空字符串。请注意GROUP_CONCAT支持ORDER BY

我还修复了这个GROUP BY子句:在非古代版本的 MySQL 中,所有非聚合列必须出现在 where 子句中(你错过了store_cat.name)。

使用您的示例数据在 DB Fiddle 上进行演示:

SELECT 
    store_cat.id_cat AS id,
    CONCAT(
        store_cat.name,
        IFNULL(
            CONCAT(
                ' (', 
                GROUP_CONCAT(store_cat_attribute.name ORDER BY store_cat_attribute.position SEPARATOR ', '),
                ')'
            ),
            ''
        )
    ) AS name, 

    COUNT(store_item.id_item) AS products, 
    store_cat.flg_public AS flg_public 
FROM 
    store_cat 
    LEFT JOIN store_item ON store_item.id_cat = store_cat.id_cat 
    LEFT JOIN store_cat_attribute ON store_cat_attribute.id_cat = store_cat.id_cat 
WHERE store_cat.id_store = 1 
GROUP BY store_cat.id_cat, store_cat.name
ORDER BY name;
| 编号 | flg_public | 姓名 | 产品 |
| --- | ---------- | --------------------- | -------- |
| 3 | 1 | 漫画 | 0 |
| 2 | 1 | 科雷亚斯 (S, M, L, XL) | 4 |
| 1 | 1 | 朱盖特 | 2 |
| 4 | | 医药 | 0 |

推荐阅读