【问题标题】:How do I combine multiple Average calculations based on multiple WHERE clauses?如何结合基于多个 WHERE 子句的多个平均值计算?
【发布时间】:2015-12-09 17:42:35
【问题描述】:

我正在尝试根据报告类型计算关闭工单所需的平均天数。

我想出了如何使用以下查询对任何一种类型的报告执行此操作:

SELECT

CONVERT(DATE,SubmitDate) as 'Date'
,SUM(DATEDIFF(DAY, SubmitDate, DateClosed)) / COUNT(*) as 'Report1Avg'

FROM Table1

    WHERE Status = 'Closed'
        AND ReportType = '1'

GROUP BY CONVERT(DATE,SubmitDate)

但是,我希望获得所有不同类型报告的平均值。我试图让结果集如下所示:

Date Submitted  Report1Avg  Report2Avg  Report3Avg  Report4Avg
9/1/2015             5          10          11          NULL
9/2/2015           NULL         22           3           5
9/3/2015            1            3          NULL        NULL

这是表格:

ticket  SubmitDate  ReportType  Status  DateClosed
  1      3/7/2014       NULL    Closed  8/18/2014
  2     3/17/2014       1       Closed  3/19/2014
  3     3/17/2014       3       Closed   4/1/2014
  4     3/18/2014       3       Closed   4/1/2014
  5     3/18/2014       3       Closed   4/1/2014
  6     3/19/2014       4       Closed  3/19/2014
  7     3/25/2014       4       Closed  3/25/2014
  8     3/25/2014       2       Closed  3/31/2014
  9     3/25/2014       NULL    Closed  3/31/2014
 10     3/25/2014       1       Closed  3/31/2014

我尝试使用 UNION 但没有奏效。创建 VIEW 也不起作用。

我发现了一些类似的帖子,但它们不涉及平均值。

感谢您的任何建议。

【问题讨论】:

  • 所以你想要按类型和提交日期的平均值?
  • 是的,如想要的结果集中所示。

标签: sql sql-server average


【解决方案1】:

这样的?

SELECT submitdate
    ,reporttype
    ,AVG(DATEDIFF(DAY, SubmitDate, DateClosed)) NUMBER_OF_DAYS
INTO #temp
FROM table1
WHERE Status = 'Closed'
GROUP BY SubmitDate,reporttype 

SELECT submitdate
    , CASE WHEN reporttype = 1 THEN (SELECT t2.NUMBER_OF_DAYS FROM #temp t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report1Avg
    , CASE WHEN reporttype = 2 THEN (SELECT t2.NUMBER_OF_DAYS FROM #temp t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report2Avg
    , CASE WHEN reporttype = 3 THEN (SELECT t2.NUMBER_OF_DAYS FROM #temp t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report3Avg
    , CASE WHEN reporttype = 4 THEN (SELECT t2.NUMBER_OF_DAYS FROM #temp t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report4Avg
FROM #temp t1

DROP TABLE #temp

或者有观点:

CREATE VIEW AVG_REPORT AS 
SELECT submitdate
    ,reporttype
    ,AVG(DATEDIFF(DAY, SubmitDate, DateClosed)) NUMBER_OF_DAYS
FROM table1
WHERE Status = 'Closed'
GROUP BY SubmitDate,reporttype 

然后:

SELECT submitdate
    , CASE WHEN reporttype = 1 THEN (SELECT t2.NUMBER_OF_DAYS FROM AVG_REPORT t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report1Avg
    , CASE WHEN reporttype = 2 THEN (SELECT t2.NUMBER_OF_DAYS FROM AVG_REPORT t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report2Avg
    , CASE WHEN reporttype = 3 THEN (SELECT t2.NUMBER_OF_DAYS FROM AVG_REPORT t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report3Avg
    , CASE WHEN reporttype = 4 THEN (SELECT t2.NUMBER_OF_DAYS FROM AVG_REPORT t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report4Avg
FROM AVG_REPORT t1

也可以像这样使用公用表表达式 (CTE):

WITH
BASE AS ( 
SELECT submitdate
    ,reporttype
    ,AVG(DATEDIFF(DAY, SubmitDate, DateClosed)) NUMBER_OF_DAYS
FROM table1
WHERE Status = 'Closed'
GROUP BY SubmitDate,reporttype
)

SELECT submitdate
    , CASE WHEN reporttype = 1 THEN (SELECT t2.NUMBER_OF_DAYS FROM BASE t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report1Avg
    , CASE WHEN reporttype = 2 THEN (SELECT t2.NUMBER_OF_DAYS FROM BASE t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report2Avg
    , CASE WHEN reporttype = 3 THEN (SELECT t2.NUMBER_OF_DAYS FROM BASE t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report3Avg
    , CASE WHEN reporttype = 4 THEN (SELECT t2.NUMBER_OF_DAYS FROM BASE t2 WHERE t1.submitdate = t2.submitdate AND t1.reporttype = t2.reporttype) END Report4Avg
FROM BASE t1

【讨论】:

  • 这会创建我正在寻找的结果集,但是有没有办法在不创建临时表的情况下做到这一点?也许首先创建一个视图?我一直在尝试自己做..但总是遇到错误。
  • 编辑了我的原始帖子并添加了视图代码。您首先必须创建一个视图,然后您可以使用后面的代码获得您想要的结果集。
  • 这非常接近我想要达到的目标。非常感谢您的帮助 hatsjie!
【解决方案2】:

您需要做的就是修复您的group by 子句:

SELECT
   CONVERT(DATE,SubmitDate) as 'Date',
   AVG(DATEDIFF(DAY, SubmitDate, DateClosed)) AS 'Report1Avg',
   ReportType
FROM Table1
   WHERE Status = 'Closed'
GROUP BY CONVERT(DATE,SubmitDate), ReportType

如果您希望根据示例格式化结果,请使用 PIVOT 语句。

【讨论】:

  • 结果集不显示其他类型报告的平均天数。
猜你喜欢
  • 2017-02-06
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 2014-05-10
  • 1970-01-01
  • 2013-07-19
相关资源
最近更新 更多