JSON 使用 Postgres 在数组中构建对象
JSON Build Object Inside an Array with Postgress
我正在为客户项目构建拖放功能,需要我的数据如下所示:
[ [Array(10)], [Array(5)], [Array(5)], [Array(5)], [Array(5)] ]
每个数组看起来像这样(每个数组都代表患者):
[ {id: 1, reccomendations: [array] } ]
推荐数组更深一层,如下所示:
["providerName1", "providerName2", "providerName3"]
我的数据库是这样设置的:
患者Table
+----+-----------+
| id | bucket_id |
+----+-----------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 2 |
| 8 | 3 |
| 9 | 4 |
| 10 | 5 |
+----+-----------+
patient_provider Table
provider_id 引用 provider.id
patient_id 引用 patiend.id
+----+-------------+-------------+
| id | provider_id | patient_id |
+----+-------------+-------------+
| 1 | 1 | 1 |
| 2 | 7 | 1 |
| 3 | 3 | 1 |
| 4 | 1 | 2 |
| 5 | 8 | 3 |
| 6 | 7 | 3 |
| 7 | 3 | 4 |
| 8 | 2 | 5 |
| 9 | 11 | 5 |
| 10 | 1 | 6 |
+----+-------------+-------------+
供应商Table
provider_id 引用 provider.id
patient_id 引用 patiend.id
+----+-------------+-------------+
| id | provider_id | patient_id |
+----+-------------+-------------+
| 1 | 1 | 1 |
| 2 | 7 | 1 |
| 3 | 3 | 1 |
| 4 | 1 | 2 |
| 5 | 8 | 3 |
| 6 | 7 | 3 |
| 7 | 3 | 4 |
| 8 | 2 | 5 |
| 9 | 11 | 5 |
| 10 | 1 | 6 |
+----+-------------+-------------+
供应商Table
有比这更多的行和列,但这是我唯一需要的列
+----+-----------+
| id | program |
+----+-----------+
| 1 | blue |
| 2 | red |
| 3 | green |
| 4 | yellow |
| 5 | pink |
| 6 | teal |
+----+-----------+
我运行这个:
SELECT "patient".id, ARRAY_AGG(DISTINCT("provider".program)) as providers FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC;
这将使我获得每个患者的提供者数组。
我也有运行这个:
SELECT JSON_AGG("patient") as patient FROM "patient"
WHERE "patient".bucket_id =1;
有了这个,我可以获得所有 buckets/columns 和属于这些列的患者。
我一直没能找到将两者组合成我需要的数据结构的方法。我已经阅读了一些关于 JSON Build Objects 的文章——这是可行的方法吗?我该怎么做?
我也愿意在服务器端执行此工作流,使用函数拼接并手动获取我需要的数据结构……如果这是更好的方法。如果您认为那是要走的路,我会怎么做?
谁能帮我,我就去买咖啡!我很乐意通过为他们构建此功能来让我的客户开心!
我用以下语句重新创建了您的案例
create table patient (id serial, bucket_id int);
insert into patient (bucket_id) values (1);
insert into patient (bucket_id) values (2);
insert into patient (bucket_id) values (3);
insert into patient (bucket_id) values (4);
insert into patient (bucket_id) values (5);
insert into patient (bucket_id) values (6);
insert into patient (bucket_id) values (2);
insert into patient (bucket_id) values (3);
insert into patient (bucket_id) values (4);
insert into patient (bucket_id) values (5);
create table patient_provider (id serial, provider_id int, patient_id int);
insert into patient_provider (provider_id, patient_id) values (1,1);
insert into patient_provider (provider_id, patient_id) values (7,1);
insert into patient_provider (provider_id, patient_id) values (3,1);
insert into patient_provider (provider_id, patient_id) values (1,2);
insert into patient_provider (provider_id, patient_id) values (8,3);
insert into patient_provider (provider_id, patient_id) values (7,3);
insert into patient_provider (provider_id, patient_id) values (3,4);
insert into patient_provider (provider_id, patient_id) values (2,5);
insert into patient_provider (provider_id, patient_id) values (11,5);
insert into patient_provider (provider_id, patient_id) values (1,6);
create table provider (id serial, program varchar);
insert into provider (program) values ('blue');
insert into provider (program) values ('red');
insert into provider (program) values ('green');
insert into provider (program) values ('yellow');
insert into provider (program) values ('pink');
insert into provider (program) values ('teal');
现在,使用您的第一个查询,并使用 json_build_object
函数,您可以实现 {id: 1, reccomendations: [array] }
(实际上并不需要外部数组)。查询如下
SELECT json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
结果是
obj
-------------------------------------------------------
{"id" : 1, "reccomendations" : ["blue","green",null]}
{"id" : 2, "reccomendations" : ["blue"]}
{"id" : 3, "reccomendations" : [null]}
{"id" : 4, "reccomendations" : ["green"]}
{"id" : 5, "reccomendations" : ["red",null]}
{"id" : 6, "reccomendations" : ["blue"]}
{"id" : 7, "reccomendations" : [null]}
{"id" : 8, "reccomendations" : [null]}
{"id" : 9, "reccomendations" : [null]}
{"id" : 10, "reccomendations" : [null]}
(10 rows)
现在,如果您想汇总上述结果,可以使用 json_agg
函数来完成。这是整体代码
With single_objects as (
SELECT json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
)
select json_agg(obj) from single_objects
和结果
json_agg
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[{"id" : 1, "reccomendations" : ["blue","green",null]}, {"id" : 2, "reccomendations" : ["blue"]}, {"id" : 3, "reccomendations" : [null]}, {"id" : 4, "reccomendations" : ["green"]}, {"id" : 5, "reccomendations" : ["red",null]}, {"id" : 6, "reccomendations" : ["blue"]}, {"id" : 7, "reccomendations" : [null]}, {"id" : 8, "reccomendations" : [null]}, {"id" : 9, "reccomendations" : [null]}, {"id" : 10, "reccomendations" : [null]}]
(1 row)
如果确实需要对每个id进行额外的数组封装,只需要在上面提到的json_build_object
调用中添加一个json_build_array
函数即可。完整查询
With single_objects as (
SELECT json_build_array(json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program)))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
)
select json_agg(obj) from single_objects
最终结果
json_agg
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[[{"id" : 1, "reccomendations" : ["blue","green",null]}], [{"id" : 2, "reccomendations" : ["blue"]}], [{"id" : 3, "reccomendations" : [null]}], [{"id" : 4, "reccomendations" : ["green"]}], [{"id" : 5, "reccomendations" : ["red",null]}], [{"id" : 6, "reccomendations" : ["blue"]}], [{"id" : 7, "reccomendations" : [null]}], [{"id" : 8, "reccomendations" : [null]}], [{"id" : 9, "reccomendations" : [null]}], [{"id" : 10, "reccomendations" : [null]}]]
(1 row)
我正在为客户项目构建拖放功能,需要我的数据如下所示:
[ [Array(10)], [Array(5)], [Array(5)], [Array(5)], [Array(5)] ]
每个数组看起来像这样(每个数组都代表患者):
[ {id: 1, reccomendations: [array] } ]
推荐数组更深一层,如下所示:
["providerName1", "providerName2", "providerName3"]
我的数据库是这样设置的:
患者Table
+----+-----------+
| id | bucket_id |
+----+-----------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 2 |
| 8 | 3 |
| 9 | 4 |
| 10 | 5 |
+----+-----------+
patient_provider Table
provider_id 引用 provider.id
patient_id 引用 patiend.id
+----+-------------+-------------+
| id | provider_id | patient_id |
+----+-------------+-------------+
| 1 | 1 | 1 |
| 2 | 7 | 1 |
| 3 | 3 | 1 |
| 4 | 1 | 2 |
| 5 | 8 | 3 |
| 6 | 7 | 3 |
| 7 | 3 | 4 |
| 8 | 2 | 5 |
| 9 | 11 | 5 |
| 10 | 1 | 6 |
+----+-------------+-------------+
供应商Table
provider_id 引用 provider.id
patient_id 引用 patiend.id
+----+-------------+-------------+
| id | provider_id | patient_id |
+----+-------------+-------------+
| 1 | 1 | 1 |
| 2 | 7 | 1 |
| 3 | 3 | 1 |
| 4 | 1 | 2 |
| 5 | 8 | 3 |
| 6 | 7 | 3 |
| 7 | 3 | 4 |
| 8 | 2 | 5 |
| 9 | 11 | 5 |
| 10 | 1 | 6 |
+----+-------------+-------------+
供应商Table
有比这更多的行和列,但这是我唯一需要的列
+----+-----------+
| id | program |
+----+-----------+
| 1 | blue |
| 2 | red |
| 3 | green |
| 4 | yellow |
| 5 | pink |
| 6 | teal |
+----+-----------+
我运行这个:
SELECT "patient".id, ARRAY_AGG(DISTINCT("provider".program)) as providers FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC;
这将使我获得每个患者的提供者数组。
我也有运行这个:
SELECT JSON_AGG("patient") as patient FROM "patient"
WHERE "patient".bucket_id =1;
有了这个,我可以获得所有 buckets/columns 和属于这些列的患者。
我一直没能找到将两者组合成我需要的数据结构的方法。我已经阅读了一些关于 JSON Build Objects 的文章——这是可行的方法吗?我该怎么做? 我也愿意在服务器端执行此工作流,使用函数拼接并手动获取我需要的数据结构……如果这是更好的方法。如果您认为那是要走的路,我会怎么做?
谁能帮我,我就去买咖啡!我很乐意通过为他们构建此功能来让我的客户开心!
我用以下语句重新创建了您的案例
create table patient (id serial, bucket_id int);
insert into patient (bucket_id) values (1);
insert into patient (bucket_id) values (2);
insert into patient (bucket_id) values (3);
insert into patient (bucket_id) values (4);
insert into patient (bucket_id) values (5);
insert into patient (bucket_id) values (6);
insert into patient (bucket_id) values (2);
insert into patient (bucket_id) values (3);
insert into patient (bucket_id) values (4);
insert into patient (bucket_id) values (5);
create table patient_provider (id serial, provider_id int, patient_id int);
insert into patient_provider (provider_id, patient_id) values (1,1);
insert into patient_provider (provider_id, patient_id) values (7,1);
insert into patient_provider (provider_id, patient_id) values (3,1);
insert into patient_provider (provider_id, patient_id) values (1,2);
insert into patient_provider (provider_id, patient_id) values (8,3);
insert into patient_provider (provider_id, patient_id) values (7,3);
insert into patient_provider (provider_id, patient_id) values (3,4);
insert into patient_provider (provider_id, patient_id) values (2,5);
insert into patient_provider (provider_id, patient_id) values (11,5);
insert into patient_provider (provider_id, patient_id) values (1,6);
create table provider (id serial, program varchar);
insert into provider (program) values ('blue');
insert into provider (program) values ('red');
insert into provider (program) values ('green');
insert into provider (program) values ('yellow');
insert into provider (program) values ('pink');
insert into provider (program) values ('teal');
现在,使用您的第一个查询,并使用 json_build_object
函数,您可以实现 {id: 1, reccomendations: [array] }
(实际上并不需要外部数组)。查询如下
SELECT json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
结果是
obj
-------------------------------------------------------
{"id" : 1, "reccomendations" : ["blue","green",null]}
{"id" : 2, "reccomendations" : ["blue"]}
{"id" : 3, "reccomendations" : [null]}
{"id" : 4, "reccomendations" : ["green"]}
{"id" : 5, "reccomendations" : ["red",null]}
{"id" : 6, "reccomendations" : ["blue"]}
{"id" : 7, "reccomendations" : [null]}
{"id" : 8, "reccomendations" : [null]}
{"id" : 9, "reccomendations" : [null]}
{"id" : 10, "reccomendations" : [null]}
(10 rows)
现在,如果您想汇总上述结果,可以使用 json_agg
函数来完成。这是整体代码
With single_objects as (
SELECT json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
)
select json_agg(obj) from single_objects
和结果
json_agg
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[{"id" : 1, "reccomendations" : ["blue","green",null]}, {"id" : 2, "reccomendations" : ["blue"]}, {"id" : 3, "reccomendations" : [null]}, {"id" : 4, "reccomendations" : ["green"]}, {"id" : 5, "reccomendations" : ["red",null]}, {"id" : 6, "reccomendations" : ["blue"]}, {"id" : 7, "reccomendations" : [null]}, {"id" : 8, "reccomendations" : [null]}, {"id" : 9, "reccomendations" : [null]}, {"id" : 10, "reccomendations" : [null]}]
(1 row)
如果确实需要对每个id进行额外的数组封装,只需要在上面提到的json_build_object
调用中添加一个json_build_array
函数即可。完整查询
With single_objects as (
SELECT json_build_array(json_build_object('id',"patient".id, 'reccomendations', ARRAY_AGG(DISTINCT("provider".program)))) as obj FROM "patient"
LEFT JOIN "patient_provider" ON "patient_provider".patient_id = "patient".id
LEFT JOIN "provider" ON "provider".id = "patient_provider".provider_id
GROUP BY "patient".id
ORDER BY "patient".id ASC
)
select json_agg(obj) from single_objects
最终结果
json_agg
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[[{"id" : 1, "reccomendations" : ["blue","green",null]}], [{"id" : 2, "reccomendations" : ["blue"]}], [{"id" : 3, "reccomendations" : [null]}], [{"id" : 4, "reccomendations" : ["green"]}], [{"id" : 5, "reccomendations" : ["red",null]}], [{"id" : 6, "reccomendations" : ["blue"]}], [{"id" : 7, "reccomendations" : [null]}], [{"id" : 8, "reccomendations" : [null]}], [{"id" : 9, "reccomendations" : [null]}], [{"id" : 10, "reccomendations" : [null]}]]
(1 row)