You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL 5.7中实现PostgreSQL json_each的JSON行提取功能

MySQL 5.7 实现 PostgreSQL json_each() 拆分JSON键值对的方案

由于MySQL 5.7不支持json_table()或json_each()这类JSON行转列函数,我们可以通过数字辅助表+JSON内置函数的组合实现相同效果,以下是具体步骤:

1. 创建测试表并插入数据

先还原PostgreSQL示例中的测试环境:

CREATE TABLE test (id INT, data JSON);

INSERT INTO test VALUES 
(1, '{"1":[0,0,1], "2":[0,1,0]}'), 
(2, '{"2":[0,0,1], "3":[0,1,0], "4":[0,0,0]}');

2. 准备数字辅助表

我们需要一个连续数字表来遍历JSON对象中的每个键。可以创建临时表(适合频繁使用):

CREATE TEMPORARY TABLE nums (n INT);
INSERT INTO nums VALUES 
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
(11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
-- 按需扩展数字范围,覆盖业务中最多的code数量即可

如果不想创建临时表,也可以用子查询动态生成数字(适合小数据量场景):

SELECT @row := @row + 1 AS n FROM 
(SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) t1,
(SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) t2,
(SELECT @row := 0) t0

3. 编写拆分查询语句

利用JSON_KEYS()获取JSON所有键,结合数字表逐个提取键值对,并拆分数组中的cur/min/max值:

SELECT 
    t.id,
    -- 提取JSON键并转为整数类型的code
    CAST(JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(t.data), CONCAT('$[', n.n-1, ']'))) AS UNSIGNED) AS code,
    -- 提取对应code数组中的current值
    JSON_UNQUOTE(JSON_EXTRACT(t.data, CONCAT('$.', JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(t.data), CONCAT('$[', n.n-1, ']'))), '[0]'))) AS cur_val,
    -- 提取对应code数组中的min值
    JSON_UNQUOTE(JSON_EXTRACT(t.data, CONCAT('$.', JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(t.data), CONCAT('$[', n.n-1, ']'))), '[1]'))) AS min_val,
    -- 提取对应code数组中的max值
    JSON_UNQUOTE(JSON_EXTRACT(t.data, CONCAT('$.', JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(t.data), CONCAT('$[', n.n-1, ']'))), '[2]'))) AS max_val
FROM test t
-- 关联数字表,只取不超过JSON键数量的数字,避免多余空行
JOIN nums n ON n.n <= JSON_LENGTH(JSON_KEYS(t.data))
ORDER BY t.id, code;

如果用动态数字子查询,替换JOIN nums n为:

JOIN (
    SELECT @row := @row + 1 AS n FROM 
    (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) t1,
    (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) t2,
    (SELECT @row := 0) t0
) n ON n.n <= JSON_LENGTH(JSON_KEYS(t.data))

执行结果

最终查询会输出和PostgreSQL示例完全一致的结果:

id | code | cur_val | min_val | max_val
---|------|---------|---------|---------
1  | 1    | 0       | 0       | 1
1  | 2    | 0       | 1       | 0
2  | 2    | 0       | 0       | 1
2  | 3    | 0       | 1       | 0
2  | 4    | 0       | 0       | 0

内容的提问来源于stack exchange,提问作者yezhy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:47:23