Sql 两个情形函数之和

Sql 两个情形函数之和,sql,sql-server,Sql,Sql Server,我试图对我刚刚在查询中创建的两个CASE函数求和。我需要这两列在我的结果集中返回,但也需要这两列的总和在另一列中返回为“DegreeDays”。我尝试了sum函数,但没有效果,我尝试了一个简单的“HeatingDegreeDays+CoolingDegreeDays as DegreeDays”,但也不起作用。建议 ,CASE WHEN TempLow > 60.5 THEN 0 WHEN ((TempHigh + TempLow

我试图对我刚刚在查询中创建的两个CASE函数求和。我需要这两列在我的结果集中返回,但也需要这两列的总和在另一列中返回为“DegreeDays”。我尝试了sum函数,但没有效果,我尝试了一个简单的“HeatingDegreeDays+CoolingDegreeDays as DegreeDays”,但也不起作用。建议

  ,CASE
    WHEN TempLow > 60.5                     THEN 0
    WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
    WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
    WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
   END AS HeatingDegreeDays

  ,CASE
    WHEN TempHigh < 66.25                   THEN 0
    WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
    WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
    WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
   END AS CoolingDegreeDays

您可以重复以下公式:

  ,CASE
    WHEN TempLow > 60.5                     THEN 0
    WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
    WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
    WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
   END +
   CASE
    WHEN TempHigh < 66.25                   THEN 0
    WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
    WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
    WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
   END AS TotalDays

一种方法是将现有查询简化为:

如果您使用的是SQL Server 2005或更高版本,这也将与以下功能一样有效:


与仅仅为了计算而重复查询的逻辑和硬编码值相比,维护这两个选项中的任何一个似乎都更好。

当您在查询的“选择”部分中派生列名时,您不能在其他部分中引用它们

您有两个基本选项:

将DegreeDays定义为重复所有逻辑或执行以下操作的两个案例语句的总和:

select ...,HeatingDegreeDays,CoolingDegreeDays,DegreeDays=HeatingDegreeDays+CoolingDegreeDays
from table
cross apply (select
CASE
    WHEN TempLow > 60.5                     THEN 0
    WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
    WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
    WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
   END AS HeatingDegreeDays

  ,CASE
    WHEN TempHigh < 66.25                   THEN 0
    WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
    WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
    WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
   END AS CoolingDegreeDays
) x

非常感谢。真的很感激。我之前试过,但我一定是把语法搞砸了。我必须说,我认为复制代码的建议不是一个好的做法,特别是当你在回答的后半部分提到了一些简单而优雅的替代方案时。这样做对性能有好处吗?@TimLehner。这两种解决方案在SQL Server中的性能应该非常相似。一些数据库,尤其是MySQL,可能会实现子查询,这可能会对性能产生很大的负面影响。啊,真不幸!戈登,谢谢你再上一课。
SELECT a.HeatingDegreeDays,
    a.CoolingDegreeDays,
    a.HeatingDegreeDays + a.CoolingDegreeDays as DegreeDays
FROM
(
    SELECT
      CASE
        WHEN TempLow > 60.5                     THEN 0
        WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
        WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
        WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
       END AS HeatingDegreeDays

      ,CASE
        WHEN TempHigh < 66.25                   THEN 0
        WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
        WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
        WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
       END AS CoolingDegreeDays
    FROM MyTable
) AS a; -- Derived tabled aliased as "a"
;WITH cte AS (
    SELECT
      CASE
        WHEN TempLow > 60.5                     THEN 0
        WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
        WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
        WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
       END AS HeatingDegreeDays

      ,CASE
        WHEN TempHigh < 66.25                   THEN 0
        WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
        WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
        WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
       END AS CoolingDegreeDays
    FROM MyTable
)
SELECT HeatingDegreeDays,
    CoolingDegreeDays,
    HeatingDegreeDays + CoolingDegreeDays as DegreeDays
FROM cte;
select ...,HeatingDegreeDays,CoolingDegreeDays,DegreeDays=HeatingDegreeDays+CoolingDegreeDays
from table
cross apply (select
CASE
    WHEN TempLow > 60.5                     THEN 0
    WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
    WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
    WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
   END AS HeatingDegreeDays

  ,CASE
    WHEN TempHigh < 66.25                   THEN 0
    WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
    WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
    WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
   END AS CoolingDegreeDays
) x
,CASE
    WHEN TempLow > 60.5                     THEN 0
    WHEN ((TempHigh + TempLow)/2) > 60.5    THEN ((60.5-TempLow)/4)
    WHEN  TempHigh >= 60.5                  THEN (((60.5 - TempLow)/2)-((TempHigh-TempLow)/4))
    WHEN TempHigh < 60.5                    THEN (60.5-(TempHigh+TempLow)/4)
   END AS HeatingDegreeDays

  ,CASE
    WHEN TempHigh < 66.25                   THEN 0
    WHEN ((TempHigh + TempLow)/2) < 66.25   THEN ((TempHigh-66.25)/4)
    WHEN  TempLow <= 66.25                  THEN (((TempHigh - 66.25)/2)-((66.25-TempLow)/4))
    WHEN TempLow > 66.25                    THEN ((TempHigh+TempLow)/2)-66.25
   END AS CoolingDegreeDays