简体   繁体   English

PostgreSQL 左连接查询与一对多关系

[英]PostgreSQL left join query with one to many relationship

I have below tables我有下表

CREATE TABLE employee(id serial PRIMARY KEY,employee jsonb);
CREATE TABLE perks_details(id serial PRIMARY KEY,details jsonb);

insert into employee(employee) values
('{"name": "name1", 
   "perks": [
             {"id": 123, "valid_from": "T23:28:56.782Z"}, 
             {"id": 456, "valid_from": "T23:28:56.782Z"}, 
             {"id": 789, "valid_from": "T23:28:56.782Z"}
            ]
  }');

insert into  perks_details(details) values('{"id":123,"detail1":"lorem","detail2":"lorem"}');
insert into  perks_details(details) values('{"id":123,"detail3":"lorem","detail4":"lorem"}');
insert into  perks_details(details) values('{"id":456,"detail5":"lorem","detail6":"lorem"}');

How to write select query from employee left join perks_details on perks id with id in perks_details table and aggregate functions so my result data looks like:如何使用 perks_details 表中的 id 和聚合函数编写来自employee左连接perks_details选择查询,以便我的结果数据如下所示:

{
  "name": "name1",
  "perks": [
    {
      "id": 123,
      "valid_from": "T23:28:56.782Z",
      "details": [
        {
          "id": 123,
          "detail1": "lorem",
          "detail2": "lorem"
        },
        {
          "id": 123,
          "detail3": "lorem",
          "detail4": "lorem"
        }
      ]
    },
    {
      "id": 456,
      "valid_from": "T23:28:56.782Z",
      "details": [
        {
          "id": 456,
          "detail5": "lorem",
          "detail6": "lorem"
        }
      ]
    },
    {
      "id": 789,
      "valid_from": "T23:28:56.782Z",
      "details": []
    }
  ]
}

I tried multiple variations and couldn't get near to a working query.我尝试了多种变体,但无法接近工作查询。 Please advise/assist me here.请在这里给我建议/帮助。

UPDATE I have this query with left join but the results are not what I expected更新我有这个带有左连接的查询,但结果不是我所期望的


    select e.id, perk, perks_details.details
      from employee AS e, jsonb_array_elements(employee->'perks') perk
    LEFT JOIN perks_details on perks_details.details -> 'id' = perk->'id'
      group by e.id, perk.value, perks_details.details;

Hi you can do it in this way:您好,您可以通过以下方式进行操作:

with cte as (
select t1.employee->>'name' "name",
t2.id, t2.valid_from, json_agg(t3.details) "details" 
from employee t1
cross join lateral jsonb_to_recordset(employee->'perks') as t2(id int,valid_from time)
left join perks_details t3 on t2.id::text=t3.details->>'id'
group by 1,2,3
)

select row_to_json(t) from (
select 
name,
json_agg(jsonb_build_object('id',id,'valid_from',valid_from,'details',details)) "perks" 
from cte group by name
) t

DEMO 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM