You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将PostgreSQL左连接结果分组为关联数组(Drizzle ORM)

Drizzle ORM左连接后合并关联数据为数组的方案

问题场景

使用Drizzle ORM执行左连接查询:

const data = await db
  .select()
  .from(projects)
  .where(eq(projects.slug, slug))
  .leftJoin(projectPdfs, eq(projects.id, projectPdfs.projectId));

查询返回包含重复projects对象的数组,每个对象对应一条pdf数据:

[
  {
    projects: { id: 1, name: 'redacted', slug: 'redacted' },
    pdfs: {
      id: 1,
      assetUrl: 'redacted',
      projectId: 1,
      requestTimeMs: '4859.872999999672'
    }
  },
  {
    projects: { id: 1, name: 'redacted', slug: 'redacted' },
    pdfs: {
      id: 2,
      assetUrl: 'redacted',
      projectId: 1,
      requestTimeMs: '4859.872999999672'
    }
  }
]

期望得到单个project对象,关联的pdf数据合并为数组:

{
  project: { id: 1, name: 'redacted', slug: 'redacted' },
  pdfs: [
    {
      id: 1,
      assetUrl: 'redacted',
      projectId: 1,
      requestTimeMs: '4859.872999999672'
    },
    {
      id: 2,
      assetUrl: 'redacted',
      projectId: 1,
      requestTimeMs: '4859.872999999672'
    }
  ]
}

尝试groupBy未得到预期结果,需解决方法。

解决方法

方法1:数据库层面聚合(PostgreSQL)

利用PostgreSQL的array_agg函数在查询中直接聚合pdf数据,同时指定返回字段并按project主键分组:

import { sql } from 'drizzle-orm';

const [result] = await db
  .select({
    project: projects,
    pdfs: sql`array_agg(${projectPdfs})`.as('pdfs'),
  })
  .from(projects)
  .where(eq(projects.slug, slug))
  .leftJoin(projectPdfs, eq(projects.id, projectPdfs.projectId))
  .groupBy(projects.id);

若需处理无pdf时的空值,可使用coalesce确保返回空数组而非null:

pdfs: sql`coalesce(array_agg(${projectPdfs}), '[]'::jsonb)`.as('pdfs'),

方法2:客户端层面处理结果

若无需修改查询逻辑,可在获取结果后手动合并数据:

const data = await db
  .select()
  .from(projects)
  .where(eq(projects.slug, slug))
  .leftJoin(projectPdfs, eq(projects.id, projectPdfs.projectId));

if (data.length === 0) {
  return null; // 处理未找到项目的情况
}

const project = data[0].projects;
const pdfs = data.map(item => item.pdfs).filter(Boolean);

const mergedResult = { project, pdfs };

内容的提问来源于stack exchange,提问作者Mohsin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:02:08