JSON构建对象在一个数组与Postgress



我正在为客户端项目构建一个拖放功能,需要我的数据看起来像这样:

[ [Array(10)], [Array(5)], [Array(5)], [Array(5)], [Array(5)] ]

其中每个数组看起来像这样(每个数组都代表患者):

[ {id: 1, reccomendations: [array] } ]

建议数组,更深一层,看起来像这样:

["providerName1", "providerName2", "providerName3"]

我的数据库设置如下:

病人表

+----+-----------+
| id | bucket_id |
+----+-----------+
|  1 |     1     |
|  2 |     2     |
|  3 |     3     |
|  4 |     4     |
|  5 |     5     |
|  6 |     6     |
|  7 |     2     |
|  8 |     3     |
|  9 |     4     |
| 10 |     5     |
+----+-----------+
<<p>patient_provider表/strong>
provider_id引用了提供商。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      |
+----+-------------+-------------+
<<p>供应商表/strong>
provider_id引用了提供商。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      |
+----+-------------+-------------+
<<p>供应商表/strong>
还有更多的行和列,但这是我唯一需要的列
+----+-----------+
| 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; 

有了这个,我可以得到所有的桶/列和属于这些列的病人。

我还没能找到一种方法将两者结合到我需要的数据结构中。我已经做了一些关于JSON构建对象的阅读-这会是一种方式吗?我该怎么做呢?我也愿意在服务器端做这个工作流程,使用一个函数来拼接并手动得到我需要的数据结构……如果这是更好的方法。如果你认为这是一条路,我该怎么做?

谁能帮我这个忙,我就给谁买咖啡!我很乐意为我的客户构建这个功能!

我用以下语句重新创建了您的案例

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)

最新更新