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

如何在同一条SQL查询中同时统计总支出和总收入两个SUM聚合值

正确实现方案

错误原因分析

你之前的代码出错核心是使用了无关联条件的隐式连接,子查询与支出查询的结果集直接生成笛卡尔积,数据行数被重复放大,因此求和结果完全不符合预期。

最优实现方案(条件聚合)

推荐直接使用条件聚合实现,仅需单次扫描事实表,性能更好,代码更简洁:

SELECT 
  O.OrganizationName, 
  D.DepartmentGroupName, 
  SUM(CASE WHEN A.AccountType = 'Expenditures' THEN F.Amount ELSE 0 END) AS [Total Expenditures],
  SUM(CASE WHEN A.AccountType = 'Revenue' THEN F.Amount ELSE 0 END) AS [Total Revenues]
FROM 
  FactFinance F 
  LEFT JOIN DimOrganization AS O ON F.OrganizationKey = O.OrganizationKey 
  LEFT JOIN DimDepartmentGroup AS D ON F.DepartmentGroupKey = D.DepartmentGroupKey 
  LEFT JOIN DimScenario AS S ON F.ScenarioKey = S.ScenarioKey 
  LEFT JOIN DimAccount AS A ON F.AccountKey = A.AccountKey 
WHERE 
  S.ScenarioName = 'Actual' 
  AND YEAR(Date) = 2020 
  AND A.AccountType IN ('Expenditures', 'Revenue')
GROUP BY 
  O.OrganizationName, 
  D.DepartmentGroupName 
ORDER BY 
  O.OrganizationName 

子查询关联实现方案

如果你更习惯用子查询拆分逻辑,可以先分别聚合支出和收入两个结果集,再通过分组字段关联,避免笛卡尔积:

SELECT
  COALESCE(E.OrganizationName, R.OrganizationName) AS OrganizationName,
  COALESCE(E.DepartmentGroupName, R.DepartmentGroupName) AS DepartmentGroupName,
  ISNULL(E.[Total Expenditures], 0) AS [Total Expenditures],
  ISNULL(R.[Total Revenues], 0) AS [Total Revenues]
FROM
-- 支出聚合子查询
(
  SELECT 
    O.OrganizationName, 
    D.DepartmentGroupName, 
    SUM(Amount) AS [Total Expenditures] 
  FROM 
    FactFinance F 
    LEFT JOIN DimOrganization AS O ON F.OrganizationKey = O.OrganizationKey 
    LEFT JOIN DimDepartmentGroup AS D ON F.DepartmentGroupKey = D.DepartmentGroupKey 
    LEFT JOIN DimScenario AS S ON F.ScenarioKey = S.ScenarioKey 
    LEFT JOIN DimAccount AS A ON F.AccountKey = A.AccountKey 
  WHERE 
    A.AccountType = 'Expenditures' 
    AND S.ScenarioName = 'Actual' 
    AND YEAR(Date) = 2020 
  GROUP BY 
    O.OrganizationName, 
    D.DepartmentGroupName 
) E
FULL OUTER JOIN
-- 收入聚合子查询
(
  SELECT 
    O.OrganizationName, 
    D.DepartmentGroupName, 
    SUM(Amount) AS [Total Revenues] 
  FROM 
    FactFinance F 
    LEFT JOIN DimOrganization AS O ON F.OrganizationKey = O.OrganizationKey 
    LEFT JOIN DimDepartmentGroup AS D ON F.DepartmentGroupKey = D.DepartmentGroupKey 
    LEFT JOIN DimScenario AS S ON F.ScenarioKey = S.ScenarioKey 
    LEFT JOIN DimAccount AS A ON F.AccountKey = A.AccountKey 
  WHERE 
    A.AccountType = 'Revenue' 
    AND S.ScenarioName = 'Actual' 
    AND YEAR(Date) = 2020 
  GROUP BY 
    O.OrganizationName, 
    D.DepartmentGroupName 
) R
ON E.OrganizationName = R.OrganizationName AND E.DepartmentGroupName = R.DepartmentGroupName
ORDER BY OrganizationName

此处使用FULL OUTER JOIN和COALESCE是为了避免某个分组只有支出没有收入、或只有收入没有支出时数据丢失,用ISNULL将空值转为0更符合业务统计习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:27:05