1

I need to represent a document structure as a JSON object to be passed to a web application to form a hierarchical tree. Of course the order of the components needs to be correct so I am searching for a way to order the parents and children. So every child should be ordered by child_order asc

How could I do that?

Here's the DDL:

CREATE TABLE documents_structure (
     id INTEGER NOT NULL
   , title CHARACTER VARYING(255) NOT NULL
   , parent_id INTEGER
   , child_order INTEGER NOT NULL
);

The Insert queries:

INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (1,'Root of the document', NULL,1);
INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (2,'First Child of root', 1,1);
INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (3,'Second Child of root', 1,2);
INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (4,'Third Child of root', 1,3);
INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (5,'First Child of Branch 1', 2,1);
INSERT INTO documents_structure (id,title,parent_id,child_order) VALUES (6,'Second Child of Branch 1', 2,2);

And the query to retrieve the JSON hierarchy:

WITH RECURSIVE document_tree("id", "title", "parent_id", "child_order", "children") AS (
  -- tree leaves (no matching children)
  SELECT c.id,c.title,c.parent_id,c.child_order, json '[]'
  FROM documents_structure c
  WHERE NOT EXISTS(SELECT id,title,parent_id,child_order FROM documents_structure AS hypothetic_child WHERE hypothetic_child.parent_id = c.id)
  UNION ALL
  SELECT (parent).id,(parent).title,(parent).parent_id,(parent).child_order, json_agg(child) AS "children"
  FROM (
    SELECT parent, child
    FROM document_tree AS child
    JOIN documents_structure parent ON parent.id = child.parent_id
  ) branch
  GROUP BY branch.parent
)
SELECT jsonb_pretty(json_agg(t)::jsonb)
FROM document_tree t
LEFT JOIN documents_structure AS hypothetic_parent ON(hypothetic_parent.id = t.parent_id)
WHERE hypothetic_parent.id = 1;

For your convenience I have made a DB fiddle

2
  • Nice question: +1 for the thoroughness (it's scarce here these days). Forgive me if I'm oversimplifying your question, but adding a order by wouldn't suffice? see fiddle: dbfiddle.uk/… Commented May 26, 2021 at 14:50
  • 1
    Thanks for your help and the thumbs up. I'm still stuck with the ordering of the array. This one seems inspiring but I did not manage to adapt it to sort my array. Commented May 26, 2021 at 16:11

0

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.