SQL查询映射表直接转换为JSON

mmv*_*sbg 2 sql postgresql json

我有一个 PostgreSQL 映射表,它保存公司员工 - 团队领导和团队成员之间的关系。调用的表leaders看起来就像这样:

leader_id | employee_id
    1     |      15
    1     |      21
    1     |      26
    2     |      76
    2     |      41
Run Code Online (Sandbox Code Playgroud)

两列都是表的外键,person该表保存诸如namedob等信息。

目标是创建包含数据的 JSON,如下所示:

{
  1: {name: "John Doe",
      person_id: 1,
      employees: {
        15: {name: "Oliver Queen",
            person_id: 15
        },
        21: {name: "Barry Alan",
            person_id: 21
        },
        26: {name: "Solomon Rondon",
            person_id: 26
        },
      }
  },
  2: {name: "Papi Hans",
      person_id: 2,
      employees: {
        76: {name: "Ashley Young",
            person_id: 76
        },
        41: {name: "Amberly Smith",
            person_id: 41
        }
      }
  },
}
Run Code Online (Sandbox Code Playgroud)

我通过编写一个带有几个联接的查询来将person表中的数据连接到和leader_id来轻松地做到这一点employee_id,然后逐行迭代结果以创建 JSON。

我的问题是,是否有一种方法可以编写查询,以便以可准备格式化的 JSON 格式显示结果,这样我就不必逐行迭代来构建它?如果有的话,效率会更高吗?

S-M*_*Man 5

演示:db<>小提琴

SELECT
    json_object_agg(person_id,                                           -- 5
        -- 4
        json_build_object('name', name, 'person_id', person_id, 'employees', employees)
    )
FROM (
    SELECT
        l.leader_id as person_id,
        p1.name as name,
        json_object_agg(l.employee_id,                                   -- 3
            json_build_object('name', p2.name, 'person_id', p2.id)       -- 2
        ) as employees
    FROM
        leader l
    JOIN person p1 ON l.leader_id = p1.id                                -- 1
    JOIN person p2 ON l.employee_id = p2.id
    GROUP BY l.leader_id, p1.name
) s
Run Code Online (Sandbox Code Playgroud)
  1. 连接person表以获取名称
  2. 为每个员工创建 JSON 对象
  3. 通过将这些 json 对象按其领导者分组为一个 JSON 对象来聚合这些 json 对象
  4. 使用员工为领导者创建 JSON 对象
  5. 将所有领​​导者对象聚合为一个 JSON 对象

在这种情况下(4)可以简化为

row_to_json(s)
Run Code Online (Sandbox Code Playgroud)

进一步阅读:Postgres JSONPostgres JSON 聚合