【问题标题】:Join all JSON object string values加入所有 JSON 对象字符串值
【发布时间】:2021-12-14 01:43:06
【问题描述】:

在 MySQL 8 JSON 列中,我有一个带有不同类型值的 JSON 对象(但没有嵌套对象)。像这样:

{
    "abc": "Something123",
    "foo": 63.4,
    "bar": "Hi world!",
    "xyz": false
}

选择连接字符串值的最简单方法是什么?例如,从上面的 JSON 中我们应该得到 "Something123 Hi world!"?

【问题讨论】:

    标签: mysql mysql-json


    【解决方案1】:

    这是 MySQL 8.0 的解决方案:

    select group_concat(json_unquote(json_extract(t.data, concat('$.', j.`key`))) separator '') as joined_string 
    from mytable cross join json_table(json_keys(mytable.data), '$[*]' columns (`key` varchar(20) path '$')) j 
    join mytable t on json_type(json_extract(t.data, concat('$.', j.`key`)))='STRING';
    

    给定示例数据的输出:

    +-----------------------+
    | joined_string         |
    +-----------------------+
    | Something123Hi world! |
    +-----------------------+
    

    但是,我想知道,如果您需要这样做,将数据存储在 JSON 中是否是个好主意。该解决方案开发复杂,难以调试或修改。

    当您确实希望 SQL 谓词将文档的字段视为离散元素时,使用 JSON 将数据存储为文档比使用普通行和列更难。

    如果您使用的是 MySQL 5.7 或更早版本,则不支持 JSON_TABLE() 函数。在这种情况下,我建议将整个 JSON 文档提取到您的应用程序中,并将其分解为您可以操作的对象。

    【讨论】:

    • 比尔,感谢您的回答。不幸的是,您的解决方案非常缓慢。在一张有 10k 行的桌子上,它运行了 10 分钟,我不得不中断它。请参阅我的答案 - 它使用类似的 JSON 函数,但在同一张桌子上花了 0.1 秒。
    • 至于“我想知道,如果你需要这样做,将数据存储在 JSON 中是否是个好主意”:是的,就我而言,JSON 效果很好。不要仅仅从我偶尔需要运行的一个奇怪的查询中得出结论。 :)
    • 很公平。确实,对于某些查询,任何类型的非规范化都是一个优势,如果这些查询是您大部分时间需要优化的查询,那么它就是一个净赢。但是每种类型的优化都会对其他类型的查询产生不利影响。
    【解决方案2】:

    这里有一个解决方案:

    SELECT GROUP_CONCAT(va SEPARATOR ' ') str_vals_only
    FROM
    (
        SELECT id, JSON_UNQUOTE(JSON_EXTRACT(my_json_col, CONCAT('$.', j.obj_key))) va
        FROM my_tbl,
        JSON_TABLE(JSON_KEYS(my_json_col), '$[*]' COLUMNS(obj_key TEXT PATH "$")) j
        WHERE JSON_TYPE(JSON_EXTRACT(my_json_col, CONCAT('$.', j.obj_key))) = 'STRING'
    ) a
    GROUP BY id
    

    不是很简单和简洁,但我想这是最好的。

    我喜欢 MySQL 中的 JSON 支持。对于某些特定情况,JSON 类型可以提供非常好的和灵活的解决方案。这就是我什至不考虑切换到 MariaDB 的主要原因(它对 JSON 的支持要有限得多)。但我希望有更多用于 JSON 操作的功能。 JSON_TABLE 功能非常强大,但可能有点复杂和冗长。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 2017-07-12
      • 2023-03-06
      相关资源
      最近更新 更多