如何将多行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
相关产品推荐
相关产品推荐

