计算GROUP BY子句中每个GROUP的AVG值

时间:2015-10-06 17:37:23

标签: sql sql-server-2005 group-by average

我正在研究SQL Server 2005中的一个查询,该查询查看记录的电话呼叫表,按一天中的小时对它们进行分组,并计算当天每小时的平均等待时间。

我有一个我觉得有效的查询,但我很难说服自己这是对的。

SELECT
    DATEPART(HOUR, CallTime) AS Hour,
    (AVG(calls.WaitDuration) / 60) AS WaitingTimesInMinutes
FROM (
    SELECT
        CallTime,
        WaitDuration
    FROM Calls
    WHERE DATEADD(day, DATEDIFF(Day, 0, CallTime), 0) = DATEADD(day, DATEDIFF(Day, 0, GETDATE()), 0)
        AND DATEPART(HOUR, CallTime) BETWEEN 6 AND 18
) AS calls
GROUP BY DATEPART(HOUR, CallTime)
ORDER BY DATEPART(HOUR, CallTime);

为了澄清我的想法,此查询会查看与今天同一天进行的所有通话,以及通话时间在6到18之间的时间 - 记录时间并在24小时内选择,所以这几小时之间是在早上6点到下午6点之间接听电话。

然后,外部查询计算WaitDuration列的平均值(并将秒转换为分钟),然后按小时对每个平均值进行分组。

我不确定的是:报告的BY HOUR平均值仅用于在该小时的时间范围内进行的呼叫吗?或者它是否使用当天和小时之间的所有呼叫计算每个报告的平均值?我知道AVG函数有一个可选的OVER / PARTITION子句,因为我使用AVG组函数已经有一段时间了。我想要的是,按小时分组的每个结果仅显示当天特定小时的平均等待时间。

感谢您抽出宝贵时间。

2 个答案:

答案 0 :(得分:2)

分组发生在从datepart(hour, ...)吐出的值上。你已经对这个值进行了过滤,所以你知道它们的范围在6到18之间。这就是分组将会看到的所有内容。

当然,datepart()函数正在寻找您正在寻找的内容,它会查看时钟并给出时间的小时部分。如果你希望你的小组与HH:00:00到HH:59:59.997一致,那么你很幸运。

我在评论中已经注意到,您可能想要将范围从6过滤到17,并且如果您更改它并将原始CallTime值与静态范围进行比较,则查询可能会表现得更好。你的推理对我来说是正确的。因为你的推理是正确的,所以根本不需要内部查询(派生表)。

如果WaitDuration是一个整数,那么你将在输出中进行十进制除法。在这种情况下你需要转换为十进制或者将除数改为十进制值,如60.00。

答案 1 :(得分:0)

  

报告的BY HOUR平均值仅用于在该小时的时间范围内进行的通话吗?

是。 {<1}}子句在分组和聚合之前应用,因此聚合将应用于符合WHERE子句且在每个组内的所有记录。