Postgres查询生成Json结构

问题描述 投票:0回答:1

我正在分享示例数据。我正在尝试创建在 postgres 数据库中运行的 sql 查询以生成以下 Json 结构。 p_id 是我的主键,我想创建电子邮件地址数组作为一个数组,并将地址和 rel 类型创建为同一个人的另一个数组。 运行查询时出错

SELECT json_agg(json_build_object(
    'p_id', p_id,
    'first_name', first_name,
    'email_details', json_agg(json_build_object(
        'email_address', email_add,
        'email_type', email_type
    )),
    'personAddresses', json_agg(json_build_object(
        'pp_code', pp_code,
        'rel_type', COALESCE(rel_type, rel_cd), -- Use COALESCE to handle either 'rel_type' or 'rel_cd'
        'addr1', addr_1
    ))
)) AS json_data
FROM (
    SELECT 
        p_id,
        first_name,
        pp_code,
        rel_type,
        rel_cd,
        addr_1,
        email_add,
        email_type
    FROM (
        SELECT '1' as p_id, 'purnima' as first_name, 1234 as pp_code, 'primary' as rel_type, null as rel_cd, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
        UNION ALL 
        SELECT '1' as p_id, 'purnima' as first_name, 6789 as pp_code, null as rel_type, 'other' as rel_cd, '99/44' as addr_1, '[email protected]' as email_add, 'other' as email_type
        UNION ALL
        SELECT '2' as p_id, 'bhanu' as first_name, 3333 as pp_code, 'primary' as rel_type, null as rel_cd, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
        UNION ALL
        SELECT '2' as p_id, 'bhanu' as first_name, 4444 as pp_code, null as rel_type, 'other' as rel_cd, '99/44' as addr_1, '[email protected]' as email_add, 'other222' as email_type
    ) sub
) subquery
GROUP BY p_id, first_name;

需要 Json 输出:

[
    {
        "p_id": 1,
        "first_name": "purnima",
        "email_details": [
            {
                "email_address": "[email protected]",
                "email_type": "work"
            },
            {
                "email_address": "[email protected]",
                "email_type": "other"
            }
        ],
        "personAddresses": [
            {
                "pp_code": 1234,
                "rel_type": "primary",
                "addr1": "37/26"
            },
            {
                "pp_code": 6789,
                "rel_type": "other",
                "addr1": "99/44"
            }
        ]
    },
    {
        "p_id": 2,
        "first_name": "bhanu",
        "email_details": [
            {
                "email_address": "[email protected]",
                "email_type": "work"
            },
            {
                "email_address": "[email protected]",
                "email_type": "other222"
            }
        ],
        "personAddresses": [
            {
                "pp_code": 3333,
                "rel_type": "primary",
                "addr1": "37/26"
            },
            {
                "pp_code": 4444,
                "rel_type": "other",
                "addr1": "99/44"
            }
        ]
    }
]
postgresql
1个回答
0
投票

我找到了解决方案。分享以防万一对某人有帮助。

SELECT json_agg(json_build_object(
    'p_id', p_id,
    'first_name', first_name,
    'email_details', email_details,
    'personAddresses', personAddresses
)) AS json_data
FROM (
    SELECT 
        p_id,
        first_name,
        (
            SELECT json_agg(json_build_object(
                'email_address', email_add,
                'email_type', email_type
            ))
            FROM (
                SELECT email_add, email_type
                FROM (
                  SELECT '1' as p_id, 'purnima' as first_name, 1234 as pp_code, 'primary' as rel_type, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
                    UNION ALL 
                    SELECT '1' as p_id, 'purnima' as first_name, 6789 as pp_code, 'other' as rel_type, '99/44' as addr_1, '[email protected]' as email_add, 'other' as email_type
                    UNION ALL
                    SELECT '2' as p_id, 'bhanu' as first_name, 3333 as pp_code, 'primary' as rel_type, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
                    UNION ALL
                    SELECT '2' as p_id, 'bhanu' as first_name, 4444 as pp_code,  'other' as rel_type, '99/44' as addr_1, '[email protected]' as email_add, 'other222' as email_type
                ) AS data
                WHERE data.p_id = sub.p_id
            ) email_details
        ) AS email_details,
        (
            SELECT json_agg(json_build_object(
                'pp_code', pp_code,
                'rel_type', rel_type,
                'addr1', addr_1
            ))
            FROM (
                SELECT pp_code,  rel_type, addr_1
                FROM (
                    SELECT '1' as p_id, 'purnima' as first_name, 1234 as pp_code, 'primary' as rel_type, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
                    UNION ALL 
                    SELECT '1' as p_id, 'purnima' as first_name, 6789 as pp_code, 'other' as rel_type, '99/44' as addr_1, '[email protected]' as email_add, 'other' as email_type
                    UNION ALL
                    SELECT '2' as p_id, 'bhanu' as first_name, 3333 as pp_code, 'primary' as rel_type, '37/26' as addr_1, '[email protected]' as email_add, 'work' as email_type
                    UNION ALL
                    SELECT '2' as p_id, 'bhanu' as first_name, 4444 as pp_code,  'other' as rel_type, '99/44' as addr_1, '[email protected]' as email_add, 'other222' as email_type
                ) AS data
                WHERE data.p_id = sub.p_id
            ) personAddresses
        ) AS personAddresses
    FROM (
        SELECT '1' as p_id, 'purnima' as first_name
        UNION ALL
        SELECT '2' as p_id, 'bhanu' as first_name
    ) sub
    GROUP BY p_id, first_name
) result;
© www.soinside.com 2019 - 2024. All rights reserved.