T-SQL多表SUM求和问题:Invoice关联Payment/Taking时Payment重复统计
解决多关联下金额求和的重复统计问题
我懂你碰到的麻烦了——因为Payment和Taking是一对多关系,直接关联三张表的话,每条Payment记录会被它关联的多条Taking记录“复制”,导致计算SUM(P.amount)时同一个Payment的金额被重复累加好几次,最终结果和父实体Invoice的金额对不上。
解决思路
核心是先对最底层的Taking数据按Payment分组求和,避免后续关联时带上来重复的Payment记录,再依次和Payment、Invoice关联计算总和。
完整SQL语句
SELECT I.invoice_number AS invoiceNumber, I.amount AS invoiceAmount, SUM(P.amount) AS paymentAmount, COALESCE(SUM(T.takingTotal), 0) AS takingAmount FROM Invoice I LEFT JOIN Payment P ON I.invoice_id = P.invoice_id LEFT JOIN ( -- 先计算每个Payment对应的Taking总金额,避免重复统计 SELECT payment_id, SUM(amount) AS takingTotal FROM Taking GROUP BY payment_id ) T ON P.payment_id = T.payment_id GROUP BY I.invoice_id, I.invoice_number, I.amount;
代码细节说明
- 子查询
T:先对Taking表按payment_id分组,算出每个Payment对应的Taking金额总和,这样每个Payment只会对应一条汇总后的Taking记录,从根源避免了重复。 LEFT JOIN:确保即使某个Invoice没有Payment,或者某个Payment没有Taking,也能正常返回数据,不会丢失任何实体的记录。COALESCE:处理Taking总金额为NULL的情况,把NULL转换成0,让结果展示更友好统一。- 最终按Invoice的唯一标识分组:保证每个Invoice只返回一条汇总记录,所有金额的计算结果都是准确匹配的。
这样处理后,paymentAmount会准确等于对应Invoice的所有Payment金额之和(和invoiceAmount匹配),takingAmount是该Invoice下所有Taking的金额总和,不会再出现重复统计的问题啦~
内容的提问来源于stack exchange,提问作者Jack Skeletron
相关产品推荐
相关产品推荐

