1

I'm sure there's a simple answer to this but I just can't find it. I need to obtain JSON array elements as rows, but their index is relevant for the subsequent processing. Here's a [very simplified] example:

id  content                                                 
--  ------------------------------------------------------------------
80  {"id":"107-80", "Sections": [{"parts":5},{"parts":8},{"parts":4}]}

I need to get:

id section section_content 
-- ------- --------------- 
80 0       {"parts":5}     
80 1       {"parts":8}     
80 2       {"parts":4}     

I've tried:

select
  id,
  row_number() over() - 1 as section, 
  jsonb_array_elements(content -> 'Sections') as section_content
from purchase

But the section column is not computed correctly, as shown below:

id  section  section_content 
--- -------- --------------- 
80  0        {"parts":5}     
80  0        {"parts":8}     
80  0        {"parts":4}     

2 Answers 2

4

You can use with ordinality

select p.id, s.*
from purchase p
  cross join jsonb_array_elements(p.content -> 'Sections') with ordinality as s(section_content, section)
Sign up to request clarification or add additional context in comments.

1 Comment

Will need to study the SQL Standard ORDINALITY clause. Thanks.
1

You can use as CTE for that

CREATE TABLE purchase (
  "id" INTEGER,
  "content" JSONB
);

INSERT INTO purchase
  ("id", "content")
VALUES
  ('80', '{"id":"107-80", "Sections": [{"parts":5},{"parts":8},{"parts":4}]}');
WITH CTE AS (select
  id,
  jsonb_array_elements(content -> 'Sections') as section_content
from purchase)
SELECT
id,  ROW_NUMBER () OVER (
      PARTITION BY id)  as section, section_content FROM CTE
id | section | section_content
-: | ------: | :--------------
80 |       1 | {"parts": 5}   
80 |       2 | {"parts": 8}   
80 |       3 | {"parts": 4}   

db<>fiddle here

2 Comments

I'm curious how the row number is assigned correcly in the absence of ORDER BY. It nevertheless works.
window function take the the order that is given in the CTE, that is why it is working, i was more currios why your query doesn't work, it seems, that jsonb_array_elements creates new rows without going to the pat where the window part recognozes it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.