【问题标题】:JSON Build Object Inside an Array with Postgress使用 Postgres 在数组中构建 JSON 对象
【发布时间】:2021-10-10 02:10:21
【问题描述】:

我正在为一个客户项目构建拖放功能,需要我的数据如下所示:

[ [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     |
+----+-----------+

patient_provider 表
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      |
+----+-------------+-------------+

提供者表
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      |
+----+-------------+-------------+

提供者表
还有比这更多的行和列,但这是我需要的唯一列

+----+-----------+
| 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 构建对象的内容——这会是要走的路吗?我该怎么做? 我也愿意在服务器端执行此工作流,使用函数拼接并手动获取我需要的数据结构......如果这是更好的方法。如果你认为这是要走的路,我会怎么做?

我会为任何可以帮助我的人买咖啡!我很想通过为他们构建这个功能来让我的客户开心!

【问题讨论】:

    标签: javascript sql json postgresql drag-and-drop


    【解决方案1】:

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

    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)
    

    【讨论】:

    • 我真的会请你喝咖啡!给我发消息:)
    • 啊哈哈哈,别担心,乐于助人!
    • 几个月后,我建立了另一个项目,不得不重新参考这个很棒的查询。 +++
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多