如何在Prisma中关联查询并统计管理员的支付总金额
解决Prisma查询管理员支付总额并包含姓名的问题
问题分析
你当前使用payment表的groupBy只能拿到admin_id和支付金额总和,但无法直接获取管理员的name和last_name——因为Prisma的groupBy仅支持基于当前表的字段分组,不能直接关联查询关联表的非分组字段。以下是两种可行的解决方案:
方案1:从管理员表直接查询(简洁高效)
直接从admins表出发,通过聚合函数计算关联支付记录的总额,同时获取管理员姓名信息:
const adminPaymentData = await prisma.admins.findMany({ select: { id: true, name: true, last_name: true, // 计算当前管理员的支付总金额 _sum: { payments: { amount: true } } } });
结构转换(匹配期望格式)
如果需要完全贴合你想要的返回结构,可以对结果做简单转换:
const formattedData = adminPaymentData.map(item => ({ admin_id: item.id, name: item.name, last_name: item.last_name, _sum: { amount: item._sum.payments.amount || 0 // 处理无支付记录的管理员 } })); console.log(formattedData);
转换后的返回示例:
[ { admin_id: 1, name: "admin-name", last_name: "admin-last-name", _sum: { amount: 1650 } } ]
方案2:分组查询+关联管理员信息(适合过滤支付场景)
如果需要先对支付记录做筛选(比如按日期范围、金额区间),可以先分组统计总额,再关联查询管理员信息:
// 1. 分组统计支付总额(可添加where条件过滤) const paymentGroups = await prisma.payment.groupBy({ by: ["admin_id"], _sum: { amount: true }, // 可选:添加过滤条件,比如只统计2024年的支付 // where: { date: { gte: new Date('2024-01-01') } } }); // 2. 批量查询对应管理员的姓名信息 const adminIds = paymentGroups.map(group => group.admin_id); const admins = await prisma.admins.findMany({ where: { id: { in: adminIds } }, select: { id: true, name: true, last_name: true } }); // 3. 合并数据 const formattedData = paymentGroups.map(group => { const matchedAdmin = admins.find(admin => admin.id === group.admin_id); return { ...group, name: matchedAdmin?.name, last_name: matchedAdmin?.last_name }; }); console.log(formattedData);
这种方式的返回结构完全符合你的期望:
[ { _sum: { amount: 1650 }, admin_id: 1, name: "admin-name", last_name: "admin-last-name" } ]
方案选择建议
- 方案1更简洁高效,适合不需要过滤支付记录的场景,一次查询即可获取所有数据。
- 方案2灵活性更高,适合需要先筛选支付记录再统计的场景。
内容的提问来源于stack exchange,提问作者Ali Aref
相关产品推荐
相关产品推荐

