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

如何将多行SQL结果合并为单个JSON/JS对象(Node.js+MySQL)

解决方案:合并重复房产记录,将租户转为数组

当然可以做到!完全不需要执行多次SQL查询,你有两种主流方案可选:在SQL层面直接聚合结果,或者在Node.js代码里处理返回的数组,下面分别说明:

方案1:SQL层面聚合(推荐,减少数据传输)

如果你的数据库支持JSON函数(比如MySQL 5.7+),可以直接用JSON_ARRAYAGG和JSON_OBJECT来把租户信息聚合为数组,这样查询返回的就是单个对象,不用后续处理。

假设你原来的查询是类似这样:

SELECT 
  p.id, p.address, p.price,
  t.id AS tenant_id, t.name AS tenant_name, t.phone AS tenant_phone
FROM property p
JOIN tenant t ON p.id = t.property_id
WHERE p.id = 123;

修改后的查询会把租户字段聚合为JSON数组:

SELECT 
  p.id, p.address, p.price,
  JSON_ARRAYAGG(
    JSON_OBJECT(
      'id', t.id,
      'name', t.name,
      'phone', t.phone
    )
  ) AS tenants
FROM property p
JOIN tenant t ON p.id = t.property_id
WHERE p.id = 123
GROUP BY p.id, p.address, p.price; -- 要把所有非聚合的房产字段都放在GROUP BY里

这样执行后,Node.js拿到的结果就是一个包含单个对象的数组,tenants字段直接是你想要的对象数组。如果mysql包没有自动解析JSON,手动执行JSON.parse(result[0].tenants)即可。

方案2:Node.js代码层面处理

如果不想修改SQL,也可以在拿到查询结果后手动合并。这里提供一个通用的处理函数:

// 假设查询返回的results是包含重复房产的数组
function mergePropertyWithTenants(results) {
  if (results.length === 0) return null;

  // 取第一条记录的房产基础信息,排除tenants字段
  const mergedProperty = { ...results[0] };
  delete mergedProperty.tenants;

  // 收集所有租户对象到数组
  mergedProperty.tenants = results.map(item => item.tenants);

  return mergedProperty;
}

// 使用示例:
const queryResults = [
  { id: 123, address: '456 Main St', tenants: { id: 1, name: 'Alice' } },
  { id: 123, address: '456 Main St', tenants: { id: 2, name: 'Bob' } }
];

const mergedResult = mergePropertyWithTenants(queryResults);
console.log(mergedResult);

执行后你会得到期望的结构:

{
  id: 123,
  address: '456 Main St',
  tenants: [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
  ]
}

如果你的查询可能返回多个房产(不是单个),可以用更通用的版本来处理所有房产:

function mergeMultipleProperties(results) {
  const propertyMap = new Map();

  results.forEach(item => {
    const propertyId = item.id; // 用房产的唯一ID作为键
    if (!propertyMap.has(propertyId)) {
      // 初始化房产对象,排除tenants
      const property = { ...item };
      delete property.tenants;
      property.tenants = [];
      propertyMap.set(propertyId, property);
    }
    // 添加当前租户到对应房产的数组
    propertyMap.get(propertyId).tenants.push(item.tenants);
  });

  return Array.from(propertyMap.values());
}

两种方案对比

  • SQL聚合:优点是减少网络传输的数据量,数据库直接返回最终结构,代码更简洁;缺点是依赖数据库的JSON函数支持,聚合逻辑写在SQL里。
  • 代码处理:优点是灵活,不需要改SQL,适合租户结构复杂或者需要额外处理的场景;缺点是会多传输重复的房产数据。

你可以根据自己的实际情况选择合适的方案~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:55:17