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

如何在PostgreSQL中利用两张表生成指定格式的JSON

如何从两张SQL表生成指定格式的JSON

以下以PostgreSQL为例(它对JSON的原生支持非常友好,适合初学者快速实现需求),给出完整实现方案,同时补充MySQL的适配版本。

完整PostgreSQL实现代码

WITH unpivoted_data AS (
    -- 把宽表转为长表,拆分年份列
    SELECT
        city,
        'val_2020' AS label,
        val_2020 AS value
    FROM data_tb
    UNION ALL
    SELECT
        city,
        'val_2021' AS label,
        val_2021 AS value
    FROM data_tb
),
chart_data_groups AS (
    -- 按年份分组,生成每个年份的chartData数组
    SELECT
        label,
        json_agg(json_build_object('key', city, 'value', value)) AS chartData
    FROM unpivoted_data
    GROUP BY label
),
unit_info AS (
    -- 处理单位和范围,把字符串转成数字数组
    SELECT
        unit,
        string_to_array(ranges, ', ')::numeric[] AS ranges
    FROM unit_tb
)
-- 最终组合成目标JSON
SELECT
    json_build_object(
        'data', json_agg(json_build_object('label', label, 'chartData', chartData)),
        'unit', (SELECT unit FROM unit_info),
        'ranges', (SELECT ranges FROM unit_info)
    ) AS result_json
FROM chart_data_groups;

分步解释(适合初学者理解)

  • 第一步:宽表转长表(Unpivot)
    原data_tb是宽表结构(每个年份单独成列),我们用UNION ALL把两个年份的数据合并,拆成「城市-年份标签-数值」的纵向结构,方便后续分组聚合。
  • 第二步:生成年份对应的chartData数组
    按label(年份)分组,用json_agg把同一年份的城市数据聚合成JSON数组,json_build_object用来构造每个key-value格式的城市数据对象。
  • 第三步:处理单位和范围数据
    把unit_tb中存储为字符串的ranges,用string_to_array拆分成数组,再转为数值类型,确保最终JSON里的范围是数字数组而非字符串。
  • 第四步:组合最终JSON结构
    用json_build_object把data数组、unit、ranges三个部分拼接成目标格式的JSON,其中data部分是通过json_agg把年份对应的JSON对象聚合而成。

MySQL适配版本

如果使用MySQL,语法会有差异,实现代码如下:

WITH unpivoted_data AS (
    SELECT city, 'val_2020' AS label, val_2020 AS value FROM data_tb
    UNION ALL
    SELECT city, 'val_2021' AS label, val_2021 AS value FROM data_tb
),
chart_data_groups AS (
    SELECT
        label,
        JSON_ARRAYAGG(JSON_OBJECT('key', city, 'value', value)) AS chartData
    FROM unpivoted_data
    GROUP BY label
),
unit_info AS (
    SELECT
        unit,
        JSON_ARRAYAGG(CAST(TRIM(val) AS UNSIGNED)) AS ranges
    FROM unit_tb,
         JSON_TABLE(
             CONCAT('[', ranges, ']'),
             '$[*]' COLUMNS(val VARCHAR(10) PATH '$')
         ) AS jt
    GROUP BY unit
)
SELECT
    JSON_OBJECT(
        'data', (SELECT JSON_ARRAYAGG(JSON_OBJECT('label', label, 'chartData', chartData)) FROM chart_data_groups),
        'unit', (SELECT unit FROM unit_info),
        'ranges', (SELECT ranges FROM unit_info)
    ) AS result_json
FROM dual;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:52:09