在不修改WHERE子句的CASE语句中实现条件求和
问题描述
现有数据表如下:
| revenue | bill_amount | invoice |
|---|---|---|
| 2 | 1 | sad |
| 2 | 5 | null |
| 5 | 7 | null |
| 5 | 2 | asdf |
需求:在不修改WHERE子句的前提下,通过CASE语句完成以下计算:
- 仅对
invoice不为null的行,分别求和revenue与bill_amount - 若
revenue总和大于bill_amount总和,返回两者差值;否则返回0
尝试的SQL语句:
SELECT SUM(CASE WHEN SUM(CASE WHEN Invoice IS NOT NULL THEN Revenue ELSE 0 END) > SUM(CASE WHEN Invoice IS NOT NULL THEN Bill_Amount ELSE 0 END) THEN(SUM(CASE WHEN Invoice IS NOT NULL THEN Revenue ELSE 0 END) - SUM(CASE WHEN Invoice IS NOT NULL THEN Bill_Amount ELSE 0 END)) ELSE 0 END) AS Total FROM Table Where Conditions
执行时报错:nested group function without GROUP BY,由于该查询属于更大的查询逻辑,修改WHERE子句会影响其他CASE语句,需要更优实现方式。
解决方案
原SQL的问题在于聚合函数嵌套使用:外层SUM内部又嵌套了SUM,这种写法在无GROUP BY的情况下不被SQL语法允许。可以通过子查询先计算聚合值,再在外层做条件判断的方式解决,同时不修改原WHERE子句:
SELECT CASE WHEN rev_sum > bill_sum THEN rev_sum - bill_sum ELSE 0 END AS Total FROM ( -- 子查询先计算invoice不为null的revenue和bill_amount总和 SELECT SUM(CASE WHEN Invoice IS NOT NULL THEN Revenue ELSE 0 END) AS rev_sum, SUM(CASE WHEN Invoice IS NOT NULL THEN Bill_Amount ELSE 0 END) AS bill_sum FROM Table WHERE Conditions ) AS agg_subquery
逻辑说明
- 子查询中先完成聚合计算:分别统计
invoice不为null时revenue和bill_amount的总和,得到两个单独的聚合值rev_sum和bill_sum - 外层查询通过
CASE语句判断两个总和的大小,返回差值或0 - 完全保留原
WHERE子句,不会影响其他关联逻辑
内容的提问来源于stack exchange,提问作者Baldie47
相关产品推荐
相关产品推荐

