【问题标题】:Am I using GROUP_CONCAT properly?我是否正确使用了 GROUP_CONCAT?
【发布时间】:2010-09-15 19:47:41
【问题描述】:

我正在选择属性并将它们加入映射表,在这些表中它们被映射到过滤器,例如位置、目的地和属性类型。

我的目标是获取所有属性,然后将它们 LEFT JOIN 连接到表中,然后基本上获取显示所有位置、属性附加到的目的地以及属性类型本身的数据。

这是我的查询:

SELECT p.slug                                        AS property_slug, 
       p.name                                        AS property_name, 
       p.founder                                     AS founder, 
       IF (p.display_city != '', display_city, city) AS city, 
       d.name                                        AS state,
       type
       GROUP_CONCAT( CONVERT(subcategories_id, CHAR(8)) )  AS foo,
       GROUP_CONCAT( CONVERT(categories_id, CHAR(8)) ) AS bah
     FROM properties AS p 
LEFT JOIN destinations AS d ON d.id = p.state 
LEFT JOIN regions AS r ON d.region_id = r.id 
LEFT JOIN properties_subcategories AS sc ON p.id = sc.properties_id 
LEFT JOIN categories_subcategories AS c  ON c.subcategory_id = sc.subcategories_id 
    WHERE 1 = 1 
      AND p.is_active = 1       
GROUP  BY p.id 

在我执行GROUP BYGROUP_CONCAT 之前,我的数据如下所示:

id  name                  type     category_id    subcategory_id    state
--------------------------------------------------------------------------
1   The Hilton Hotel      1        1              2                 7
1   The Hilton Hotel      1        1              3                 7
1   The BlaBla Resort     2        2              5                 7

GROUP BYGROUP_CONCAT 之后变成...

id  name                  type     category_id    subcategory_id    state
--------------------------------------------------------------------------
1   The Hilton Hotel      1        1, 1           2, 3              7
1   The BlaBla Resort     2        1              3                 7

这是一次性获取属性的所有可能映射的首选方式,将GROUP_CONCAT 转换为这样的 CSV?

使用这些数据,我可以渲染类似...

<div class="property" categories="1" subcategories="2,3">
   <h2>{property_name}</h2>
   <span>{property_location}</span>
</div>

然后使用 Javascript 显示/隐藏基于用户是否单击具有 subcategory="2" 属性的锚点,它将隐藏其 subcategories 属性内没有 2 的每个 .property价值。

【问题讨论】:

    标签: sql mysql group-concat


    【解决方案1】:

    我相信你想要这样的东西:

    CREATE TABLE property (id INT NOT NULL PRIMARY KEY, name TEXT);
    
    INSERT
    INTO    property
    VALUES
            (1, 'Hilton'),
            (2, 'Astoria');
    
    CREATE TABLE category (id INT NOT NULL PRIMARY KEY, property INT NOT NULL);
    
    INSERT
    INTO    category
    VALUES
            (1, 1),
            (2, 1),
            (3, 2);
    
    CREATE TABLE subcategory (id INT NOT NULL PRIMARY KEY, category INT NOT NULL);
    
    INSERT
    INTO    subcategory
    VALUES
            (1, 1),
            (2, 1),
            (3, 2),
            (5, 3),
            (6, 3),
            (7, 3);
    
    
    SELECT  id, name,
            CONCAT(
            '{',
            (
            SELECT  GROUP_CONCAT(
                    '"', c.id, '": '
                    '[',
                    (
                    SELECT  GROUP_CONCAT(sc.id ORDER BY sc.id SEPARATOR ', ' )
                    FROM    subcategory sc
                    WHERE   sc.category = c.id
                    ),
                    ']' ORDER BY c.id SEPARATOR ', ')
            FROM    category c
            WHERE   c.property = p.id
            ), '}')
    FROM    property p;
    

    会输出这个:

    1   Hilton     {"1": [1, 2], "2": [3]}
    2   Astoria    {"3": [5, 6, 7]}
    

    最后一个字段是格式正确的JSON,它将类别 ID 映射到子类别 ID 的数组。

    【讨论】:

      【解决方案2】:

      您应该添加 DISTINCT,并可能添加 ORDER BY:

      GROUP_CONCAT(DISTINCT CONVERT(subcategories_id, CHAR(8)) 
        ORDER BY subcategories_id)  AS foo,
      GROUP_CONCAT(DISTINCT CONVERT(categories_id, CHAR(8)) 
        ORDER BY categories_id) AS bah
      

      如果你想这样称呼它,它就是“去规范化的”。如果这是用于渲染的最佳表示是另一个问题,我认为这很好。有人可能会说这是 hack,但我想这还不错。

      顺便说一句,“类型”后面好像少了一个逗号。

      【讨论】:

        猜你喜欢
        • 2011-07-14
        • 2014-07-19
        • 2017-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-03
        • 2010-10-17
        • 1970-01-01
        相关资源
        最近更新 更多