如何正确使用 sum (case ... when ... then ...)?
Posted
技术标签:
【中文标题】如何正确使用 sum (case ... when ... then ...)?【英文标题】:How to use sum (case ... when ... then ...) properly? 【发布时间】:2019-09-12 17:01:44 【问题描述】:我想将具有特定值的行汇总为特定列。 早些时候我做了这样的事情:
SELECT date AS 'Date',
sum(CASE license_id WHEN 'a' THEN data.Amount ELSE 0 END) AS 'a',
sum(CASE license_id WHEN 'b' THEN data.Amount ELSE 0 END) AS 'b',
sum(
CASE license_id WHEN '1' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '2' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '3' THEN data.Amount ELSE 0 END
) AS 'c',
sum(
CASE license_id WHEN '10' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '11' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '12' THEN data.Amount ELSE 0 END
) AS 'd'
FROM ...
...
这正是我想要的,但现在我有了一个新场景。 我需要总结不同的温度结果。以下代码不起作用,只是为了解释我想要的:
SELECT date AS 'Date',
sum(CASE license_id WHEN 'b' THEN data.Amount ELSE 0 END) AS 'b',
sum( CASE license_id WHEN '1' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '2' THEN data.Amount ELSE 0 END +
CASE license_id WHEN '3' THEN data.Amount ELSE 0 END +
b
) AS 'c',
FROM ...
...
所以我的问题是因为这只是整个 SELECT 语句的一部分:
我可以让CASE ... WHEN ... THEN ... + CASE ... WHEN ... THEN ... + CASE ... WHEN ... THEN ...
更简单吗?
是否有可能实现我可以在进一步计算中使用临时结果?
提前感谢您的帮助!
【问题讨论】:
能否提供表格结构、示例输入数据和示例结果行?每个案例末尾的+
是做什么用的?
首先,您可以删除部分ELSE 0
,因为它默认为null,即未添加。
使用一种情况,而不是把几种情况相加。
另外,您可以使用IN
,如CASE license_id IN ('1', '2', '3') THEN ...
。
您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称(并且您使用的是无效的标准 SQL)。请为您正在使用的数据库产品添加tag
【参考方案1】:
问题是 b
不被理解 - 或者充其量是对表中列的引用而不是您的表达式。
这是 SQL 的一般属性。您不能在同一查询的SELECT
、FROM
或WHERE
子句中重复使用列别名。您在 mysql 中基本上有三个选项:
这种情况下,其实还有第四种选择,因为重写查询简化了逻辑:
select date,
sum(case license_id when 'b' then data.Amount else 0 end) AS b,
sum(case when license_id in ('b', '1', '2', '3') then data.Amount else 0
end) as c,
from ...
注意case
的形式有点不同,在when
之后是一个布尔条件。
此外,列别名不需要单引号。如果您想防止代码出现问题,请仅对字符串和日期常量使用单引号。
【讨论】:
"或 最好 引用列 ...",我会说相反,“或 最差 引用一列……”。 非常感谢您的建议,但我担心这不会解决我的问题。是否可以有像 @var = ('1', '2', '3') 之类的变量? @DerKnecht 。 . .这(以及其他答案)回答了您提出的问题。如果您有不同的问题,那么也许您应该将其作为 新 问题提出。【参考方案2】:由于您总是在测试 license_id
并且总是对 data.Amount
求和,因此 IN
条件可以为您节省大量输入:
SELECT
sum(CASE license_id WHEN 'a' THEN data.Amount END) AS a,
sum(CASE license_id WHEN 'b' THEN data.Amount END) AS b,
sum(CASE WHEN license_id IN ('b','1','2','3') THEN data.amount END) as c
...
您没有指定您使用的是哪个 RDBMS,但我敢打赌,如果它支持 CASE
表达式,那么它可能也支持 IN
。
【讨论】:
谢谢@TheImpaler 我已经摆脱了我的copypasta示例。 @TheImpaler,取决于您是否希望不存在的 license_id 为 0 或 null。 @TheImpaler, dbfiddle.uk/… @jarlh 圣鳄梨酱。你说的对。我在 PostgreSQL、MariaDB、DB2、Oracle 和 MySQL 中测试了您的示例。以上是关于如何正确使用 sum (case ... when ... then ...)?的主要内容,如果未能解决你的问题,请参考以下文章
逗号分隔的结果在 SQL 中使用 SUM(CASE WHEN
如何在 SELECT 查询中使用聚合函数和 CASE WHEN THEN