如何正确使用 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 的一般属性。您不能在同一查询的SELECTFROMWHERE 子句中重复使用列别名。您在 mysql 中基本上有三个选项:

使用子查询 重复表达式 使用 CTE

这种情况下,其实还有第四种选择,因为重写查询简化了逻辑:

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

如何在 MySQL 中正确使用 CASE..WHEN

如何在 SELECT 查询中使用聚合函数和 CASE WHEN THEN

sum case when 条件筛选

如何正确使用case when表达式 和 decode函数?

请教一下数据库case when then end空值问题