1

I have JSON and I'm sending it to postgresql function. I need to insert every object inside weekDays array in a separate row and every key inside the object in a separate column and it needs to include weekId.

My table looks like this: enter image description here

{
   "weekId":20,
   "weekDays":[
      {
         "day_of_week":"Monday",
         "working_hours":22.5,
         "description":"text",
         "date":"May 22, 2019"
      },
      {
         "day_of_week":"Tuesday",
         "working_hours":22.5,
         "description":"text",
         "date":"May 22, 2019"
      }
   ]
} 

So what is the best way to do this? I can do something like this:

INSERT INTO timesheet(day_of_week, working_hours, description, date)
SELECT day_of_week, working_hours, description, date
FROM json_to_recordset(weeks_days)
AS x(day_of_week varchar, working_hours REAL, description text, date timestamp);

But how to include weekId that is not in array?

1 Answer 1

1

Use ->> operator to get weekId as text and cast it to integer, e.g.:

WITH my_data(jsonb_column) AS (
VALUES
('{
   "weekId":20,
   "weekDays":[
      {
         "day_of_week":"Monday",
         "working_hours":22.5,
         "description":"text",
         "date":"May 22, 2019"
      },
      {
         "day_of_week":"Tuesday",
         "working_hours":22.5,
         "description":"text",
         "date":"May 22, 2019"
      }
   ]
}'::jsonb)
)

INSERT INTO timesheet(weekid, day_of_week, working_hours, description, date)
SELECT (jsonb_column->>'weekId')::int, day_of_week, working_hours, description, date
FROM my_data
CROSS JOIN jsonb_to_recordset(jsonb_column->'weekDays')
AS x(day_of_week varchar, working_hours REAL, description text, date timestamp)
RETURNING *;

 id | weekid | day_of_week | working_hours | description |        date         
----+--------+-------------+---------------+-------------+---------------------
  1 |     20 | Monday      |          22.5 | text        | 2019-05-22 00:00:00
  2 |     20 | Tuesday     |          22.5 | text        | 2019-05-22 00:00:00
(2 rows)

In Postgres 11 you can cast jsonb number to integer (-> instead of ->>):

SELECT (jsonb_column->'weekId')::int, day_of_week, working_hours, description, date
Sign up to request clarification or add additional context in comments.

2 Comments

It works! just one question... WITH my_data(jsonb_column) AS ( VALUES() ) Creates something like temp table?
Yes, in some sense. It's a handy way to prepare input data in the form of a table. Read more in the documentation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.