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

时间:2019-02-22 00:48:58

标签: mysql sql concat group-concat

我需要从store_cat获取类别的列表,从子项COUNT从store_item(产品数量)中获取子项GROUP_CONCAT,从store_cat_attributes(属性列表)中获取。关键是,使用CONCAT函数需要在父表(store_cat)的GROUP_CONCAT列上附加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值显示值:

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的属性列表,如下所示:

  • Comidas
  • Correas(S,M,L,XL)
  • Juguetes
  • 医学

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

要解决的问题:

  1. 仅当存在属性时,才使用GROUP_CONCAT将属性连接到类别名称。

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

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

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

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        |