【问题标题】:Double nested array_agg(row_to_json())双嵌套array_agg(row_to_json())
【发布时间】:2020-09-21 01:30:11
【问题描述】:

我有三张桌子:人、宠物、小狗。

一个人可以养很多宠物。 一只宠物可以养很多只幼崽。

我构建我的架构并像这样插入数据:

create table person (
  id serial primary key,
  name text
);

create table pet (
  id serial primary key,
  owner int,
  name text
);

create table pup (
  id serial primary key,
  parent int,
  name text
);

insert into person (name) values
('tom'), ('dick'), ('harry');

insert into pet (owner, name) values
(1, 'fluffy'),
(2, 'snuffles'),
(1, 'mr potato head');

insert into pup (parent, name) values
(1, 'fluffy jr'),
(1, 'fluffy II');

我们看到人“汤姆”有两只宠物“蓬松”和“土豆头先生”。 我们看到人“迪克”有一只宠物“鼻烟”。

我们看到宠物“fluffy”有两只小狗“fluffy jr”和“fluffy II”。

我正在尝试获得一个双重嵌套数组,但我只能获得一层嵌套。这是我的 sql fiddle - http://sqlfiddle.com/#!17/03659/2 他们查询我使用:

select p.*,
       array_agg(row_to_json(
         pet
       )) filter (where pet.id is not null) as pets
from person p
left outer join pet pet
on pet.owner = p.id
group by p.id;

我希望“tom”的条目对“pups”进行双重嵌套:

{
  "id": 1,
  "name": "tom",
  {
    "id": 1,
    "owner": 1,
    "name": "fluffy",
    "pups": [
      {
        "id": 1,
        "parent": 1,
        "name": "fluffy jr"
      },
      {
        "id": 2,
        "parent": 1,
        "name": "fluffy II"
      }
    ]
  }
}

有人知道如何获得这种双重嵌套吗?

【问题讨论】:

    标签: sql arrays json postgresql subquery


    【解决方案1】:

    您可以在子查询中按父级聚合“pups”,然后在外部查询中按人聚合:

    select pn.*,
        jsonb_agg(jsonb_build_object(
            'id',    pt.id,
            'owner', pt.owner,
            'name',  pt.name,
            'pups',  pp.pups
        )) filter(where pt.id is not null) pets
    from person pn
    left join pet pt 
        on pt.owner = pn.id
    left join (select parent, jsonb_agg(pp) pups from pup pp group by parent) pp 
        on pp.parent = pt.id
    group by pn.id;
    

    请注意,这使用 JSON 聚合函数 json[b]_agg() 而不是 array_agg() 来生成 JSON 数组。我也从json 切换到jsonb - 后者应该是首选,因为它提供了比前者更多的功能。

    【讨论】:

    • 这太有趣了,谢谢。我注意到在第一个jsonb_build_object 中我们不能像原来那样做pt.*,这可能吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2016-10-06
    相关资源
    最近更新 更多