如何用SQL合并统计语句并高效计算个人收支余额
合并分组统计与JOIN计算收支余额的高效SQL写法
你的思路是对的——先分别分组统计收入和支出,再通过JOIN合并计算余额,但你写的语句有两个小问题:子查询没加别名导致字段引用错误,以及未处理NULL值(如果用户没有支出记录,sum_expenses会是NULL,减法结果也会变成NULL)。
正确的合并写法(仅统计有收入的用户)
SELECT s.id_person, (s.sum_revenue - COALESCE(e.sum_expenses, 0)) AS balance FROM (SELECT id_person, SUM(revenue_d) AS sum_revenue FROM sales GROUP BY id_person) s LEFT OUTER JOIN (SELECT id_person, SUM(expenses_d) AS sum_expenses FROM expenses GROUP BY id_person) e ON s.id_person = e.id_person;
关键修正点:
- 给两个子查询分别起别名
s(对应收入统计结果)和e(对应支出统计结果),确保JOIN条件能正确识别字段 - 用
COALESCE(e.sum_expenses, 0)把NULL的支出值替换为0,避免余额计算出现无效的NULL - 高效性说明:先分组聚合再JOIN是最优方案——分组后数据量大幅减少,JOIN的运算开销会比直接关联两张原始大表再聚合低很多。如果
id_person字段有索引,分组和JOIN的性能还能进一步提升。
扩展:统计所有有收支记录的用户(含仅支出无收入的情况)
如果需要覆盖那些只有支出没有收入的用户,改用FULL OUTER JOIN,同时处理收入的NULL值:
SELECT COALESCE(s.id_person, e.id_person) AS id_person, COALESCE(s.sum_revenue, 0) - COALESCE(e.sum_expenses, 0) AS balance FROM (SELECT id_person, SUM(revenue_d) AS sum_revenue FROM sales GROUP BY id_person) s FULL OUTER JOIN (SELECT id_person, SUM(expenses_d) AS sum_expenses FROM expenses GROUP BY id_person) e ON s.id_person = e.id_person;
内容的提问来源于stack exchange,提问作者MSM
相关产品推荐
相关产品推荐

