在Case语句中执行Count()和Avg()

时间:2018-02-27 22:35:57

标签: tsql ssrs-2014

我使用此CASE声明显示按年龄组分组的总访问次数和平均访问时长:

    CASE WHEN AgeCalcSort = 0 AND  AgeCalcSort <= 1 then (
        Count(VisitID),
        AVG(DATEDIFF(dd,StartDate,EndDate ))
        )
    WHEN AgeCalcSort >= 2 AND  AgeCalcSort <= 17 then (
                Count(VisitID),
        AVG(DATEDIFF(dd,StartDate,EndDate ))
        )
    WHEN AgeCalcSort >= 18 AND  AgeCalcSort <= 64 then (
                Count(VisitID),
        AVG(DATEDIFF(dd,StartDate,EndDate ))
        )
    WHEN AgeCalcSort >= 65 then (
                Count(VisitID),
        AVG(DATEDIFF(dd,StartDate,EndDate ))
        )
    END,

结果应如下所示:

Age 1 Count  Age 1 Avg LOS      Age 2 Count  Age 1 Avg LOS      Age 3 Count  Age 3 Avg LOS      Age 4 Count     Age 4 Avg LOS
5           5.3                 18          9.2                 20              12              0               0   

任何人都可以承认我做错了什么,或者更好的方法来达到最终结果?提前致谢。

2 个答案:

答案 0 :(得分:1)

case expression返回单个值,然后您可以计算或平均值。

无法从单case expression生成多列输出。因此,对于每个想要的输出列,您需要一个case表达式,如下所示:

select
      COUNT(CASE WHEN AgeCalcSort = 0  AND  AgeCalcSort <= 1 then VisitID end)
    , AVG(CASE WHEN   AgeCalcSort = 0  AND  AgeCalcSort <= 1 then DATEDIFF(dd,StartDate,EndDate ) end)
    , COUNT(CASE WHEN AgeCalcSort = 2  AND  AgeCalcSort <= 17 then VisitID end)
    , AVG(CASE WHEN   AgeCalcSort = 2  AND  AgeCalcSort <= 17 then DATEDIFF(dd,StartDate,EndDate ) end)
    , COUNT(CASE WHEN AgeCalcSort = 18 AND  AgeCalcSort <= 64 then VisitID end)
    , AVG(CASE WHEN   AgeCalcSort = 18 AND  AgeCalcSort <= 64 then DATEDIFF(dd,StartDate,EndDate ) end)
    , COUNT(CASE WHEN AgeCalcSort = 65 then VisitID end)
    , AVG(CASE WHEN   AgeCalcSort = 65 then DATEDIFF(dd,StartDate,EndDate ) end)
from ...

注意:

  • 将每个case表达式放在相关的聚合函数
  • count()函数忽略NULL,因此如果不满足when条件,则计数不会增加
  • 虽然T-SQL文档有时会在技术上使用术语“case statement”,但这是不正确的;例如完整的选择查询是“语句”,“表达式”评估为单个值,因此正确的术语是case expression

答案 1 :(得分:1)

你提到了2点:

  

1)任何人都可以提出我做错了什么

  • 您在查询中错误地使用了CASE表达式。
  • CASE语句中满足某些条件时,不能返回2列。
  • 根据 Microsoft文档CASE评估条件列表并返回多个可能的结果表达式之一。
  • 查看此Microsoft白皮书以获取进一步研究。 URL
  

2)实现最终结果的更好方法

  • 可以通过多种方式实现这一目标。
  • 以下是一种简单的方法。尝试以下查询:

    SELECT
        SUM(CASE WHEN AgeCalcSort = 0 AND AgeCalcSort <= 1 THEN 1 ELSE 0 END) [Age 1 Count], 
        AVG(CASE WHEN AgeCalcSort = 0 AND AgeCalcSort <= 1 THEN DATEDIFF(DAY,StartDate,EndDate) ELSE NULL END) [Age 1 Avg LOS]
        SUM(CASE WHEN AgeCalcSort = 2 AND AgeCalcSort <= 17 THEN 1 ELSE 0 END) [Age 2 Count], 
        AVG(CASE WHEN AgeCalcSort = 2 AND AgeCalcSort <= 17 THEN DATEDIFF(DAY,StartDate,EndDate) ELSE NULL END) [Age 2 Avg LOS]
        SUM(CASE WHEN AgeCalcSort = 18 AND AgeCalcSort <= 64 THEN 1 ELSE 0 END) [Age 3 Count], 
        AVG(CASE WHEN AgeCalcSort = 18 AND AgeCalcSort <= 64 THEN DATEDIFF(DAY,StartDate,EndDate) ELSE NULL END) [Age 3 Avg LOS]
        SUM(CASE WHEN AgeCalcSort >= 65 THEN 1 ELSE 0 END) [Age 4 Count], 
        AVG(CASE WHEN AgeCalcSort >= 65 THEN DATEDIFF(DAY,StartDate,EndDate) ELSE NULL END) [Age 4 Avg LOS]
    FROM [YourTableName]
    

查询说明

  • 我使用SUM实现了计数,如果您查看任何计数逻辑,您会注意到它在满足条件1其他0时会说。然后使用SUM汇总。因此,所有1最终都会计算出来。
  • 平均而言,你会注意到条件不满意我正在使用NULL,这是故意的,以避免错误的数学。
  • for for TSQL查询AVG (2,4,NULL) 3 AVG (2,4,0) 2 NULL {{1}} {{1}}因此,在您的情况下{{1}}将有助于避免混乱平均值。