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

Node.js中mysql2如何将关联表结果封装为对象数组

解决mysql2查询关联表后自动嵌套posts数组的问题

方法1:利用MySQL的JSON聚合函数(推荐)

直接在SQL层将posts聚合为JSON数组,mysql2会自动将JSON字段解析为JavaScript数组,无需额外处理。

适用于MySQL 5.7及以上版本(支持JSON函数):

SELECT 
  U.id,
  U.name,
  COALESCE(
    JSON_ARRAYAGG(
      JSON_OBJECT(
        'id', P.id,
        'user_id', P.user_id
        -- 可添加posts表其他需要的字段
      )
    ), JSON_ARRAY()
  ) AS posts
FROM users U
LEFT JOIN posts P ON U.id = P.user_id
GROUP BY U.id, U.name;

查询后mysql2直接返回目标结构:

[
  {
    id: 1,
    name: 'John',
    posts: [
      { id: 1, user_id: 1 },
      { id: 2, user_id: 1 },
      { id: 3, user_id: 1 }
    ]
  }
]

用COALESCE是为了处理用户无对应posts的情况,确保posts字段始终是数组而非NULL。

方法2:mysql2的nestTables配置(配合简易分组)

如果不想修改SQL,可以开启mysql2的nestTables选项,将不同表的字段嵌套到对应对象中,再用简单逻辑分组:

const [rows] = await this.connection.query(
  'SELECT * FROM users U LEFT JOIN posts P on U.id = P.user_id',
  { nestTables: true } // 开启表字段嵌套,避免字段名冲突
);

const usersMap = new Map();
for (const row of rows) {
  const userId = row.U.id;
  if (!usersMap.has(userId)) {
    usersMap.set(userId, { ...row.U, posts: [] });
  }
  // 仅当存在有效post时添加
  if (row.P.id) {
    usersMap.get(userId).posts.push(row.P);
  }
}
const result = Array.from(usersMap.values());

关于mysql2底层自动处理的说明

mysql2作为轻量MySQL客户端,核心是准确返回数据库原生查询结果,关联结果的分组属于业务逻辑层面的转换,默认不会内置这类功能。SQL聚合的方式更高效——聚合逻辑由数据库处理,既减少客户端数据传输量,也降低前端处理成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:25:23