简体   繁体   中英

Convert rows of one table to json and add it to another table PostgreSQL

I have two tables progress_report and progress_report_activity.

CREATE TABLE PROGRESS_REPORT
(
  REPORT_ID VARCHAR NOT NULL,
  PCP_PATIENT_ID VARCHAR NOT NULL,
  VC_PRODUCT_ID VARCHAR ,
  REPORT_DURATION_DAYS INTEGER NOT NULL,
  REPORT_GENERATION_DATE BIGINT,
  IS_REPORT_READ BOOLEAN ,
  ACTIVITY_DETAILS JSONB,
  SYMPTOMS_DETAILS JSONB,
  PRIMARY KEY (REPORT_ID)
);

CREATE TABLE PROGRESS_REPORT_ACTIVITY
(
REPORT_ACTIVITY_ID VARCHAR NOT NULL,
REPORT_ID VARCHAR NOT NULL,
ACTIVITY_CONFIG_ID VARCHAR NOT NULL,
ACTIVITY_ASSISTANCE VARCHAR NOT NULL,
PRIMARY KEY (REPORT_ACTIVITY_ID)
)

I need to convert ACTIVITY_CONFIG_ID and ACTIVITY_ASSISTANCE from PROGRESS_REPORT_ACTIVITY to json and add this json to ACTIVITY_DETAILS column in PROGRESS_REPORT.

I tried to form json using this query:

SELECT ROW_TO_JSON(t) FROM (SELECT activity_config_id, activity_assistance FROM progress_report_activity pra inner join progress_report pr on pr.report_id=pra.report_id) t

But the issue PROGRESS_REPORT_ACTIVITY will return multiple rows for the same report_id, which is common in both the tables.

Sample data:

insert into progress_report_activity values ('1','1','11','qwerty')
insert into progress_report_activity values ('3','1','13','qwertyDup')
insert into progress_report_activity values ('2','2','12','qwerty2')
insert into progress_report_activity values ('10','2','11','qwerty12223')

insert into progress_report values ('1','123','taltz',123,123456,true,null,null);
insert into progress_report values ('10','123','olumiant',123,123456,true, null,null)

Expected output: Below are two different formats for the output, can you suggest queries for both.

1]sample progress_report row should look like:

  1,123,taltz,123,123456,true, {"activity_config_id" : ["11","13"], "activity_assistance" : ["qwerty","qwertyDup"]}

2]sample progress_report row:

1,123,taltz,123,123456,true, {"activity" : [{"activity_config_id":"11",
    "activity_assistance" : "qwerty"},
    {"activity_config_id":"13",
    "activity_assistance" : "qwertyDup" }]

9.2 is very limited with json support . solution wont look good:

t=# with p as (SELECT pr.report_id,array_agg(activity_config_id) activity_config_id, array_agg(activity_assistance) activity_assistance FROM progress_report_activity pra inner join progress_report pr on pr.report_id=pra.report_id group by pr.report_id)
select row_to_json(j), report_id from p, (select activity_config_id,activity_assistance from p) j;
                                   row_to_json                                   | report_id
---------------------------------------------------------------------------------+-----------
 {"activity_config_id":["11","13"],"activity_assistance":["qwerty","qwertyDup"]} | 1
(1 row)

now when you have you json prepared per report_id, update it:

t=# with p as (SELECT pr.report_id,array_agg(activity_config_id) activity_config_id, array_agg(activity_assistance) activity_assistance FROM progress_report_activity pra inner join progress_report pr on pr.report_id=pra.report_id group by pr.report_id)
, d as (select row_to_json(j), report_id from p, (select activity_config_id,activity_assistance from p) j)
update progress_report set ACTIVITY_DETAILS = row_to_json
from d where progress_report.report_id = d.report_id
;
UPDATE 1

update to achieve second expected result I don't limit to 9.2 (as aparently OP has 9.6):

 with c as (select report_id,json_agg(json_build_object('activity_config_id',activity_config_id,'activity_assistance',activity_assistance)) AS j from progress_report_activity group by report_id)
update progress_report pr set ACTIVITY_DETAILS = concat('{"activity" :',j,'}')::json
from c where c.report_id = pr.report_id;

http://sqlfiddle.com/#!17/13555/2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM