【问题标题】:MySQL JSON_OBJECT instead of GROUP_CONCATMySQL JSON_OBJECT 而不是 GROUP_CONCAT
【发布时间】:2018-02-17 16:03:47
【问题描述】:

我有以下 sql 查询,使用 GROUP_CONCAT 可以正常工作:

SELECT orders.created_at,products.title, o_p.qty AS qty,

    (SELECT GROUP_CONCAT(features.title,"\:", o_p_f.value, features.unit) FROM order_product_features AS o_p_f 
     LEFT JOIN product_features ON product_features.id = o_p_f.product_feature_id
    LEFT JOIN features ON o_p_f.product_feature_id = product_features.id
     AND features.id = product_features.feature_id

     WHERE o_p_f.order_product_id = o_p.id
) AS prop
FROM orders
LEFT JOIN order_products AS o_p ON o_p.order_id = orders.id

LEFT JOIN products ON products.id = o_p.product_id

以上查询返回结果如下图所示:

现在,我想将GROUP_CONCAT 替换为JSON_OBJECT换句话说,我想让prop 字段成为JSON 对象。我尝试了以下方法:

SELECT orders.created_at,products.title, o_p.qty AS qty,

    JSON_OBJECT((SELECT GROUP_CONCAT("title",features.title,"value", o_p_f.value, 'unit',features.unit) FROM order_product_features AS o_p_f 
     LEFT JOIN product_features ON product_features.id = o_p_f.product_feature_id
    LEFT JOIN features ON o_p_f.product_feature_id = product_features.id
     AND features.id = product_features.feature_id

     WHERE o_p_f.order_product_id = o_p.id
)) AS prop
FROM orders
LEFT JOIN order_products AS o_p ON o_p.order_id = orders.id

LEFT JOIN products ON products.id = o_p.product_id

但是,上面的查询返回错误:

1582 - 调用本机函数“JSON_OBJECT”时的参数计数不正确

【问题讨论】:

  • @Blag 简单地说,正如我在问题“......或者换句话说,我想让 prop 字段成为 JSON 对象”,即我需要一种方法来转换道具字段转换为 JSON 对象。您将提供的任何使用 GROUP_CONCAT 的示例,然后使用任何方式将该连接的字符串转换为 JSON 都足以解决我的问题。
  • 请提供一些测试数据和您的创建表,没有...
  • 根据docs,JSON_OBJECT 接受偶数个参数,对应于key1、value1、key2、value2 等。你传递给它一个参数,即GROUP_CONCAT 返回的字符串。跨度>
  • 我会尝试消除对 group_concat 的调用。您似乎没有 group by 子句,所以我想知道您为什么要使用 group_concat 而不是 concat。我认为 json_object(select “title”, features.title, “value”, ...etc) 将是要走的路。

标签: mysql sql json mysql-5.7


【解决方案1】:

开启≥5.7.22

JSON_OBJECTAGG(key, value) 更可能是您所追求的。

mysql> SELECT o_id, attribute, value FROM t3;
+------+-----------+-------+
| o_id | attribute | value |
+------+-----------+-------+
|    2 | color     | red   |
|    2 | fabric    | silk  |
|    3 | color     | green |
|    3 | shape     | square|
+------+-----------+-------+
4 rows in set (0.00 sec)

mysql> SELECT o_id, JSON_OBJECTAGG(attribute, value) FROM t3 GROUP BY o_id;
+------+----------------------------------------+
| o_id | JSON_OBJECTAGG(attribute, name)        |
+------+----------------------------------------+
|    2 | {"color": "red", "fabric": "silk"}     |
|    3 | {"color": "green", "shape": "square"}  |
+------+----------------------------------------+
1 row in set (0.00 sec)

但是由于您没有提供表结构,因此我无法帮助您进行查询。

您对unit 的处理似乎会给您一些额外的工作,因为聚合函数使用Key=>Value 并且不会采用第三个参数...

开启 ≥ 5.7

你必须做一些手工:

SELECT 
o_id, 
CONCAT(
    '{', 
    GROUP_CONCAT(
        TRIM(
            LEADING '{' FROM TRIM(
                TRAILING '}' FROM JSON_OBJECT(
                    `attribute`, 
                    `value`
                    )
                )
            )
        ),
    '}'
    ) json 
FROM t3 
GROUP BY o_id

≥5.5

没有任何JSON函数:

SELECT 
o_id, 
CONCAT(
    '{', 
    GROUP_CONCAT(
        CONCAT(
            '"',
            `attribute`,
            '":"',
            `value`,
            '"'
            )
        ),
    '}'
    ) json 
FROM t3 
GROUP BY o_id 

【讨论】:

  • 这是个好主意,但是,这个功能是从 MySQL 5.7.22 开始添加的,现在可能很多共享主机都找不到它。
  • @SaidbakR 更新了 ≥5.7 和 ≥5.5 的版本。 (如果没问题,别忘了将您的问题标记为已解决)
  • 不要忘记逃避你的价值观,否则这将是一个巨大的错误来源。 (例如,当您的文本包含“-s”时)
猜你喜欢
  • 2020-05-01
  • 2023-02-04
  • 2011-01-31
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 2016-11-23
  • 1970-01-01
相关资源
最近更新 更多