如何正确使用sum(case ... when ... then ...)?

时间:2019-04-23 13:31:03

标签: mysql sql innodb conditional-aggregation

我想将具有特定值的行作为特定列求和。 之前我做了这样的事情:

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语句的一部分:

  • 我能以某种方式使这种情况变得简单吗?………………………………………………………………………………………… li>
  • 是否有可能将临时结果用于进一步的计算?

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

由于您一直在测试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

答案 1 :(得分: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之后。

此外,列别名也不需要单引号。如果要防止代码出现问题,请仅对字符串和日期常量使用单引号。