从 MySQL 查询中的 JSON 个对象属性创建 JSON 个对象

Creating JSON objects from JSON object properties in MySQL query

我需要使用 MySQL 5.7 从 JSON 对象中的属性创建一个 JSON 对象列表。我有这个结构:

{
    "X": 1,
    "Y": 1,
    "Z": 55,
    "A": 2,
    "B": 33
}

我希望将属性分隔为对象并按这些对象中的键排序,如下所示:

[
    {"A": 2},
    {"B": 3},
    {"X": 1},
    {"Y": 1},
    {"Z": 55}
]

我尝试将键和值分开,然后可能会以某种方式合并它

TRIM(LEADING '[' FROM TRIM(TRAILING ']' FROM JSON_KEYS(letters_and_values)))           as letters,
TRIM(LEADING '[' FROM TRIM(TRAILING ']' FROM JSON_EXTRACT(letters_and_values, '$.*'))) as values,

但我觉得我把它复杂化了。有谁知道达到预期结果的最简单方法吗?

MySQL 5.x 中没有合适的解决方案可以将 JSON 拆分为行进行排序。一个丑陋的解决方案是使用包含值 0, 1, 2, ... 的 table 进行交叉连接,并使用 JSON_EXTRACT(..., '$[...]') 从 JSON 中提取每个项目。一旦您将每个项目放在其行中,您就可以排序和重新组合:

SELECT
    CONCAT('[', GROUP_CONCAT(CONCAT('{', k, ':', v, '}') ORDER BY k DESC SEPARATOR ','), ']')
FROM (
    SELECT
        JSON_EXTRACT(JSON_KEYS(json), CONCAT('$[', i, ']')) AS k,
        JSON_EXTRACT(json, CONCAT('$.', JSON_EXTRACT(JSON_KEYS(json), CONCAT('$[', i, ']')))) AS v
    FROM t
    INNER JOIN (
        SELECT 0 AS i UNION ALL
        SELECT 1      UNION ALL
        SELECT 2      UNION ALL
        SELECT 3      UNION ALL
        SELECT 4      UNION ALL
        SELECT 5      UNION ALL
        SELECT 6      UNION ALL
        SELECT 7      UNION ALL
        SELECT 8      UNION ALL
        SELECT 9
    ) AS numbers ON i < JSON_LENGTH(json)
) AS x

Demo

在MySQL8中你可以使用JSON_TABLE函数来操作JSON.

请注意,JSON 对象中的键没有任何自然顺序。 {"x": 1, "y": 2}{"y": 2, "x": 1} 相同。