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

如何在SQL中对JSON导入的动态键数据实现类UNPIVOT转换?

如何在SQL中转换以对象ID为顶级键的JSON数据?

场景说明

第一种常规JSON结构

这种结构可以直接导入SQL,生成扁平化的单行数据:

{
    "person": {
        "name": "Todd",
        "age": 10
    }, 
    "address": {
        "name": "18B Victory",
        "zip": 20019
    }
}

导入后结构:

person.name      person.age       address.name       address.zip
"Todd"           10               "18B Victory"      20019

第二种待转换的JSON结构

这种以对象ID为顶级键的结构,直接导入SQL会生成横向扩展的列,不符合需求:

{
    "X1AB": {
        "name": "Todd",
        "age": 10
    }, 
    "Y2AL": {
        "name": "Brad",
        "age": 20
    }
}

直接导入后的结构:

X1AB.name     X1AB.age        Y2AL.name       Y2AL.age
"Todd"        10              "Brad"          20

我们需要将其转换为如下纵向结构:

_prefix         name         age
X1AB            "Todd"        10
Y2AL            "Brad"        20

实现方案

可以实现,无需依赖PIVOT/UNPIVOT,利用各SQL数据库的JSON解析函数即可完成,以下是主流数据库的具体实现:

SQL Server

使用OPENJSON函数解析JSON,它会返回顶级键值对,再提取内部字段:

DECLARE @json NVARCHAR(MAX) = N'{
    "X1AB": {
        "name": "Todd",
        "age": 10
    }, 
    "Y2AL": {
        "name": "Brad",
        "age": 20
    }
}'

SELECT 
    [key] AS _prefix,
    JSON_VALUE(value, '$.name') AS name,
    JSON_VALUE(value, '$.age') AS age
FROM OPENJSON(@json)

PostgreSQL

使用json_each(或jsonb_each)展开顶级键值对,再提取内部属性:

WITH json_data AS (
    SELECT '{
        "X1AB": {
            "name": "Todd",
            "age": 10
        }, 
        "Y2AL": {
            "name": "Brad",
            "age": 20
        }
    }'::json AS data
)
SELECT
    key AS _prefix,
    (value->>'name') AS name,
    (value->>'age')::INT AS age
FROM json_data, json_each(data)

MySQL

结合JSON_TABLE和JSON_KEYS提取顶级键,再通过路径解析内部字段:

SET @json = '{
    "X1AB": {
        "name": "Todd",
        "age": 10
    }, 
    "Y2AL": {
        "name": "Brad",
        "age": 20
    }
}';

SELECT
    jt._prefix,
    JSON_UNQUOTE(JSON_EXTRACT(@json, CONCAT('$."', jt._prefix, '".name'))) AS name,
    JSON_EXTRACT(@json, CONCAT('$."', jt._prefix, '".age')) AS age
FROM JSON_TABLE(
    JSON_KEYS(@json),
    '$[*]' COLUMNS (_prefix VARCHAR(10) PATH '$')
) AS jt;

核心思路

所有方案的核心逻辑一致:先将JSON的顶级键值对展开,把顶级键映射为_prefix列,再从每个键对应的JSON值中提取name、age等内部字段,最终得到纵向的目标数据结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:20:34