Retrieve the data in JSON format including the child elements from a PostgreSQL

I have data from a table in Postgres that I need to be returned in Json format with its children properly ordered. So far, I haven't found a solution to achieve this. Is there a way in PostgreSQL to order the parent modules along with their child modules? Here is an example:

[
  {
    "id_module": 1,
    "id_parent_module": null,
    "module_code": "001.",
    "name_module": "Atoridad Fiscal",
    "desc_module": "Atoridad Fiscal",
    "children": [{
        "id_module": 2,
        "id_parent_module": 1,
        "module_code": "001.002",
        "name_module": "Recibidos",
        "desc_module": "Recibidos"
      },
      {
        "id_module": 3,
        "id_parent_module": 1,
        "module_code": "001.003.",
        "name_module": "Enviados",
        "desc_module": "Enviados"
      },
      {
        "id_module": 4,
        "id_parent_module": 1,
        "module_code": "001.004.",
        "name_module": "Archivados",
        "desc_module": "Archivados"
      }]
  },
  {
    "id_module": 5,
    "id_parent_module": null,
    "module_code": "005.",
    "name_module": "Configuraciones",
    "desc_module": "Configuraciones",
    "children": [{
      "id_module": 14,
      "id_parent_module": 5,
      "module_code": "005.014.",
      "name_module": "Medios Contacto",
      "desc_module": "Medios Contacto"
    }]
  },
  {
    "id_module": 6,
    "id_parent_module": null,
    "module_code": "006.",
    "name_module": "Mensajes",
    "desc_module": "Bandeja del contribuyente",
    "children": [{
        "id_module": 7,
        "id_parent_module": 6,
        "module_code": "006.007.",
        "name_module": "Recibidos",
        "desc_module": "Recibidos"
      },
      {
        "id_module": 8,
        "id_parent_module": 6,
        "module_code": "006.008.",
        "name_module": "Enviados",
        "desc_module": "Enviados"
      },
      {
        "id_module": 22,
        "id_parent_module": 6,
        "module_code": "006.022.",
        "name_module": "Buscador de Mensajes",
        "desc_module": "Buscador de Mensajes"
      }]
   }
]

I have attempted using

SELECT array_to_json(array_agg(row_to_json(alias))) FROM (select * from my table ) alias
but it only returns the JSON without organizing the data with its children.

Answer №1

If your table data has a depth of up to two levels, you can achieve the desired outcome by utilizing multiple non-recursive subqueries. However, if your data is nested at n levels, it is necessary to employ a recursive cte to establish the hierarchy:

with recursive cte(id, p, js) as (
   select t.id_module, t.id_parent_module, json_agg(t.jsn) 
   from (select m.id_module, m.id_parent_module, 
             json_build_object('id_module', m1.id_module, 
                'id_parent_module', m1.id_parent_module, 
                 'module_code', m1.module_code, 
                 'name_module', m1.name_module, 
                 'desc_module', m1.desc_module) jsn 
         from modules m join modules m1 on m1.id_parent_module = m.id_module 
         where not exists (select 1 from modules m2 where m2.id_parent_module = m1.id_module)) t  
         group by t.id_module, t.id_parent_module
   union all
   select t.id_module, t.id_parent_module, json_agg(t.jsn) 
   from (select m.id_module, m.id_parent_module, 
             json_build_object('id_module', m2.id_module, 
                'id_parent_module', m2.id_parent_module, 
                'module_code', m2.module_code, 
                'name_module', m2.name_module, 
                'desc_module', m2.desc_module, 
                'children', c.js) jsn 
         from modules m join cte c on m.id_module = c.p join modules m2 on m2.id_module = c.id) t 
         group by t.id_module, t.id_parent_module
)
select jsonb_pretty(t.result::jsonb) from (
    select json_agg(json_build_object('id_module', m2.id_module, 'id_parent_module', m2.id_parent_module, 'module_code', m2.module_code, 'name_module', m2.name_module, 'desc_module', m2.desc_module, 'children', c.js)) result 
    from cte c join modules m2 on c.id = m2.id_module where c.p is null) t

For results based on input data with similar depths as your example, refer to this link.

To see how the same query functions with data exceeding a depth of > 2, visit this page.

Answer №2

Execute the jsonb_agg() function in phases:


with kids as (
  select id_parent_module, 
         jsonb_agg(to_jsonb(my_data) order by id_module) as children
    from my_data
   where id_parent_module is not null
   group by id_parent_module
), parents as (
  select p.*, c.children
    from my_data p
         join kids c on c.id_parent_module = p.id_module
)
select jsonb_pretty(jsonb_agg(to_jsonb(parents) order by id_module)) as final_result
  from parents;

Check out the db<>fiddle here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Android to Retrieve JSON Data from a Web Address

Currently, I am working on converting my website into an Android app and one of the pages on my website displays data populated via JSON. The URL generates different JSON data with the same structure based on the passed ID. I have already implemented the l ...

What is the best way to extract a value from a JSON object?

I am having trouble deleting data from both the table and database using multiple select. When I try to delete, it only removes the first row that is selected. To get the necessary ID for the WHERE condition in my SQL query, I used Firebug and found this P ...

Uniform JSON format in REST API

After extensive research on the web, I have yet to find a clear answer to a simple query: should JSON formats be consistent for all HTTP verbs when it comes to a specific resource? For instance: GET http://example.com/api/articles yields [ { id: 1 ...

Utilizing AngularJS filter in JavaScript without AngularJS Framework

This is a test to experiment and learn. Currently, I have a JSON object called obj. My goal is to utilize the angular Json filter to format this JSON object and display it in the chrome console. This should be achieved without the need for any button click ...

Tips for fixing the issue "Uncaught SyntaxError: Unexpected token S in JSON at position 0"

After referencing sols of SO, I am still unable to solve the error. I have a file dashboard.html which contains search conditions. When clicked, it calls loadtable.js. This loadtable.js file uses search.php to retrieve rows from a table. However, encount ...

How to incorporate a popup modal in your project and where should you place the DialogService constructor

Currently, I am in the process of developing a CRUD ASP.NET Core application using Angular 2 and Typescript. Prior to incorporating a popup feature, this was my output: https://i.stack.imgur.com/vHvCC.png My current task involves placing the "Insert or e ...

Regular expression for substituting pairs of keys and values within JSON data

Having trouble removing a specific key and value pair from a JSON string in Java. I've tried using regex but can't seem to get it right. Can someone help me figure out what I'm missing? "appointment_request_id": "77bl5ii169daj ...

Is there a way to verify if the JSON Object array includes the specified value in an array?

I am working with JSON data that contains categories and an array of main categories. categories = [ {catValue:1, catName: 'Arts, crafts, and collectibles'}, {catValue:2, catName: 'Baby'}, {catValue:3, catName: 'Beauty ...

Customize the theme type with @mui/system

Is there a way to customize my theme settings in @mui/system? While using the sx prop in Stack, the theme is defined in createTheme.d.ts, but it seems like there isn't an option to extend or override it. To work around this limitation, I have been u ...

SQL: Retrieve the initial instance only

I don't frequently use SQL and couldn't find a similar query in my records, so I'm seeking help with this simple query: I am looking for a query that returns personID along with only the first instance of seenTime Records: seenID | personI ...

What is the process for assigning a value of type NSURL to type UIimage?

Hey there, I've got a Json file: { "Name":"Car", "Picture":"http://www.starpropertiesindia.com/blog/wp-content/uploads/2016/08/kochi1.jpg", "Description":"Ford" } that contains information about a car which includes name, picture and descri ...

The module "node_modules/puppeteer/lib/types" does not contain the export "Cookie"

Currently facing an issue with puppeteer types. I am attempting to import the Cookie type, but it seems to be not functioning on versions above 6.0.0. import { Cookie } from 'puppeteer'; Here is the error message: /node_modules/puppeteer/lib/typ ...

Exploring the process of transforming a JSON array into separate JSON objects using Node.js

I am struggling with converting a JSON array to multiple JSON objects in Node.js. I've attempted using loops but have been unsuccessful. I'm seeking assistance to send the data as separate objects, not an array. router.get('/frontpage-mobil ...

Text box accompanied by an Ext JS Combo box

Recently diving into Ext JS, I'm curious if there's a possibility to achieve something like this. I acknowledge the option of using an editable Combo box instead, but my interest lies in exploring alternative methods. ...

Display real-time information fetched from sessionStorage (in JSON format) on a Listview widget

In my session, I have the following JSON data stored: Prescription: [{"medID":"id1","medName":"name1","medQty":"qty1","medDirec":"Directions1"}, {"medID":"id2","medName":"name2","medQty":"qty2","medDirec":"Directions2"}] I am looking to automatically dis ...

Display identical text using JavaScript filter

My search filter highlight is currently displaying [object Object] instead of <mark>match values</mark> when replacing the values. This is the code I am using: this.countries.response.filter((val) => { const position = val.value.toLowerCa ...

Issue: "The argument provided must be a specific string, not a string or an array of strings."

Currently, I am tackling a Vue project that incorporates TypeScript and axios for handling API requests. While working on the Reset Password component, the resetPassword function within the auth.ts file appears as follows: resetPassword(password1: string, ...

What is the best way to invoke a function that is declared within a React component in a TypeScript class?

export class abc extends React.Component<IProps, IState> { function(name: string) { console.log("I hope to invoke this function"+ name); } render() { return ( <div>Hello</div> ); } } Next, can I cal ...

Ways to capture targeted requests

Utilizing NestJS and Angular 2, I have noticed that both frameworks have a similar approach when it comes to working with Interceptors. I am currently looking for the best practice to identify specific requests in order to perform additional tasks. When d ...

Data from the session is not displayed when a redirect occurs

On the main page, I include the following code: <?php $required = array('post_question'); // Checking if post field is not empty $error = false; foreach($required as $field) { if (empty($_POST[$field])) { $error = true; } } if(isset($_POST[&a ...