合并一对多连接查询的行

Merge rows on join queries on one-to-many

我是 SQL 的新手,有两个 Postgresql 表:

CREATE TABLE project (
    id uuid DEFAULT uuid_generate_v4 (),
    name VARCHAR(100) NOT NULL,
    creator_id uuid NOT NULL
);

CREATE TABLE task (
    id uuid DEFAULT uuid_generate_v4 (),
    name VARCHAR(100) NOT NULL,
    project_id uuid NOT NULL,
);

我是 运行 一个非常简单的加入 :

SELECT project.*, task.name as task_name 
FROM project 
INNER JOIN task ON task.project_id = 
WHERE project.id = 

结果是:

[
  {
    id: '5936d843-aca0-4453-ad24-a7b3a6b90393',
    name: 'Test project',
    creator_id: '2e0e73af-e824-46a2-89ee-c08cf9c5de7a',
    task_name: 'Test task'
  },
  {
    id: '5936d843-aca0-4453-ad24-a7b3a6b90393',
    name: 'Test project',
    creator_id: '2e0e73af-e824-46a2-89ee-c08cf9c5de7a',
    task_name: 'Test task 2'
  }
]

我的问题是,是否可以合并 id 上的那些行以获得更像这样的结果:

[
  {
    id: '5936d843-aca0-4453-ad24-a7b3a6b90393',
    name: 'Test project',
    creator_id: '2e0e73af-e824-46a2-89ee-c08cf9c5de7a',
    tasks: [
      {
        task_name: 'Test task'
      },
      {
        task_name: 'Test task 2'
      }
  }
]

我知道有一些东西可以帮助我实现这一点,比如使用 COALESCE、json_build_object 或 json_agg。但这让我为看起来很简单的东西构建“复杂”查询,所以你知道是否有更简单的方法来做到这一点,或者我应该只获取第一个结果并用我选择的语言处理它(这里 javascript) 根据需要合并 ?

您需要按项目分组并聚合项目任务。

SELECT p.*, 
       jsonb_agg(jsonb_build_object('task_name', t.name)) tasks
FROM project p 
INNER JOIN task t ON t.project_id = p.id
WHERE p.id =  -- or whatever your selection condition is
group by p.id, p.name, p.creator_id;

如果project.id是主键那么

group by p.id, p.name, p.creator_id

可以简化为

group by p.id;

我假设预期的 JSON 数组结果是在逻辑层或类似 ORM 的东西中形成的。如果您希望(顺便说一句更好)查询本身 returns 结果作为 JSON 数组,那么

select jsonb_agg(to_josnb(t.*)) from
(
 ... the query above ...
) t;