【问题标题】:MySQL group and merge JSON valuesMySQL 分组和合并 JSON 值
【发布时间】:2016-05-03 07:17:09
【问题描述】:

我正在使用一些本机 JSON 字段将有关某些应用程序实体的信息存储在 MySQL 5.7.10 数据库中。每个“实体”可以有 'N' 行,并且需要汇总 JSON 对象并将其合并在一起,并且任何冲突的键都应该替换而不是合并。我可以通过代码做到这一点,但如果我能在 MySQL 中本地高效地做到这一点,那就更好了。

我已经尝试使用 GROUP_CONCAT 和 JSON_MERGE 的组合,但我遇到了两个问题:

  1. JSON_MERGE 不会将GROUP_CONCAT 的结果作为有效参数
  2. JSON_MERGE 组合冲突的键而不是替换它们。我真正需要的是更多的 JSON_SET,但使用“N”个 JSON 文档而不是“键、值”表示法。

当前的 MySQL JSON 实现是否可以做到这一点?

【问题讨论】:

  • 换货的规则是什么?您可以发布示例数据和预期结果吗?
  • 我没有要测试的数据,但我想看看 concat(group_concat()) 是否允许 JSON_MERGE?

标签: mysql json


【解决方案1】:

您可以执行以下操作:

SELECT
    CAST(CONCAT(
        '[',
        GROUP_CONCAT(
            DISTINCT JSON_OBJECT(
                'foo', mytable.foo,
                'bar', mytable.bar
            )
        ),
        ']'
    ) AS JSON) AS myJsonArr
FROM mytable
GROUP BY mytable.someGroup;

【讨论】:

    【解决方案2】:
    1. JSON_MERGE 不会将 GROUP_CONCAT 的结果作为有效参数

    GROUP_CONCAT 给出a,b,c,d,而不是 JSON 数组。使用JSON_ARRAYAGG(在 MySQL 5.7.22 中引入),它的工作方式与 group_concat 类似,但提供了一个正确的数组 ["a", "b", "c", "d"],应该被 JSON 函数接受。

    在 5.7.22 之前,您需要使用一种解决方法:

    cast(
      concat('["',                                    // begin bracket and quote
             group_concat(`field` separator '", "'),  // separator comma and quotes
             '"]'                                     // end quote and bracket
     ) as json
    )
    
    1. JSON_MERGE 合并冲突的键而不是替换它们。我真正需要的是更多的 JSON_SET,但使用“N”个 JSON 文档而不是“键、值”表示法。

    改用JSON_MERGE_PATCH,正如 MySQL 5.7.22 中引入的那样。 JSON_MERGEJSON_MERGE_PRESERVE 的同义词。

    https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html


    阅读我的Best Practices for using MySQL as JSON storage

    【讨论】:

      【解决方案3】:

      JSON 值的聚合

      对于 JSON 值的聚合,SQL NULL 值与其他数据类型一样被忽略。除 MIN()、MAX() 和 GROUP_CONCAT() 之外,非 NULL 值将转换为数字类型并进行聚合。对于数字标量的 JSON 值,转换为数字应该会产生有意义的结果,尽管(取决于值)可能会发生截断和精度损失。转换为其他 JSON 值的数量可能不会产生有意义的结果。

      我刚刚在 mysql docs找到了这个

      【讨论】:

        【解决方案4】:

        首先,GROUP_CONCAT 只返回一个字符串,所以你必须转换它。其次,有一个函数完全符合您的要求,称为 JSON_MERGE_PATCH()。请尝试以下操作:

        SELECT
            JSON_MERGE_PATCH(
                yourExistingJson,
                CAST(
                    CONCAT(
                        '[',GROUP_CONCAT(myJson),']'
                    )
                AS JSON)
            ) AS myJsonArray
        ....
        

        刚刚意识到你的版本。您必须升级到 5.7.22 或更高版本。你的情况有可能吗?如果没有,可能还有其他方法,但它们不会优雅:(

        【讨论】:

          猜你喜欢
          • 2019-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-25
          • 1970-01-01
          • 2012-08-16
          相关资源
          最近更新 更多