将非空 CONCAT_GROUP 连接到 MySQL 中的父列

Concatenate non empty CONCAT_GROUP to parent column in MySQL

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

这很好用:

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 值在没有属性时显示 empty 值:

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 列应该包含带有 CONCATGROUP_CONCAT 的属性列表,就像这样:

这是当前 SQLfiddle。顺便说一句,当前 GROUP_CONCAT 中的属性顺序有些问题。它正在显示 (XL, S, M, L) 而不是 (S, M, L, XL).

需要解决的问题:

  1. 使用GROUP_CONCAT只有在有属性的情况下才将属性拼接到类目名称

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

有什么想法吗?谢谢!

以下表达式应该 return 您期望的结果:

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)。

Demo on 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;
| id  | flg_public | name                  | products |
| --- | ---------- | --------------------- | -------- |
| 3   | 1          | Comidas               | 0        |
| 2   | 1          | Correas (S, M, L, XL) | 4        |
| 1   | 1          | Juguetes              | 2        |
| 4   |            | Medicinas             | 0        |