简体   繁体   中英

How do I produce a JSON document from PostgreSQL 1:n tables?

I have the table "client" with:

id  name     registered_on  status
--  -------  -------------  ------
 1  Alice    2020-03-04     a     
 2  Vincent  2020-03-05     p     
 3  Anne     2020-03-06     a     

And the table "account" with:

client_id  account_number  type  balance
---------  --------------  ----  -------
        1  300-1           CHK       100
        2  307-5           SAV        24
        2  307-6           CHK       350

I created them in DB Fiddle .

Now, I need a SQL query to produce the 1:n JSON document.

There's a 1:n relationship between the tables and some clients may not have an account (such as "Anne"):

[
  {
    "id":1,
    "name":"Alice",
    "registered_on":"2020-03-04",
    "status":"a",
    accounts: [ 
      {
        "account_number": "300-1",
        "type": "CHK",
        "balance": 100.00
      }
    ]
  },
  {
    "id":2,
    "name":"Vincent",
    "registered_on":"2020-03-05",
    "status":"p",
    accounts: [ 
      {
        "account_number": "307-5",
        "type": "SAV",
        "balance": 24
      },
      {
        "account_number": "307-6",
        "type": "CHK",
        "balance": 350
      }
    ]
  },
  {
    "id":3,
    "name":"Anne",
    "registered_on":"2020-03-06",
    "status":"a",
    accounts: [ ]
  }  
]

The result is a simple join (probably an outer join) that I know how to do. I just don't get how to produce a JSON document from it.

I suppose the column id of the client table is a primary key. The key functions to use are to_jsonb() and jsonb_agg().

select jsonb_pretty(jsonb_agg(r))
from (
    select
        to_jsonb(c) || jsonb_build_object(
            'accounts', 
            coalesce(nullif(jsonb_agg(to_jsonb(a)- 'client_id'), '[null]'), '[]')
            ) as r
    from client c
    left join account a on client_id = id
    group by c.id
    ) s

Db<>fiddle.

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