我正在分享示例数据。我正在尝试创建在 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"
}
]
}
]
我找到了解决方案。分享以防万一对某人有帮助。
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;