TSQL - 如何获取组中的总计数作为子查询的一部分

TSQL - How can I get the total count in a group as part of a subquery

我需要获取当天每位用户每小时的总通话量,然后计算该用户接听的来电百分比。归根结底的目的是计算每个用户每小时的奖金池百分比。

我可以得到大部分数据,但无法计算每小时的总调用量,即每个小时组的总调用量...

假设以下数据(必要时将日期更改为当前日期):

EnteredBy           EnteredOn
Lisa Scandaleyes    05/07/2017 07:40:04
Fred Smith          05/07/2017 07:54:17
A User              05/07/2017 08:15:06
Johnny Johnson      05/07/2017 08:20:57
A User              05/07/2017 09:27:29
A User              05/07/2017 09:36:16
A User              05/07/2017 09:42:36
A User              05/07/2017 10:09:57

我每小时可以轻松接到电话:

SELECT DATEPART(HOUR, [EnteredOn]) AS Hour, Count(*) as CallsPerHour
FROM CallHandlingCallData 
WHERE DATEDIFF(d, EnteredOn, GetDate())= 0 
GROUP BY DATEPART(HOUR, [EnteredOn])
ORDER BY Hour;

我还可以获得每个用户每小时的通话次数:

SELECT DATEPART(HOUR, [EnteredOn]) AS Hour, EnteredBy, Count(*) as CallsTaken
FROM CallHandlingCallData 
WHERE DATEDIFF(d,EnteredOn, GetDate())= 0
GROUP BY DATEPART(HOUR, [EnteredOn]), EnteredBy
ORDER BY Hour, EnteredBy;

我什至可以获得几乎所有我想要的东西,除了 TotalCalls 值,因此百分比基于当天的所有呼叫:

SELECT Hour, EnteredBy, CallsTaken, TotalCalls, 
CAST(CallsTaken AS Decimal(10,2)) * 100 / CASE TOTALCALLS WHEN 0 THEN 1 ELSE TotalCalls END AS Percentage 
FROM
(
    SELECT DATEPART(HOUR, [EnteredOn]) AS Hour, EnteredBy, Count(*)as CallsTaken, 
    (SELECT Count(*) FROM CallHandlingCallData WHERE DATEDIFF(d, EnteredOn, GetDate())= 0) AS TotalCalls
    FROM CallHandlingCallData
    WHERE DATEDIFF(d,EnteredOn, GetDate())= 0
    GROUP BY DATEPART(HOUR, [EnteredOn]), EnteredBy
) data
ORDER BY Hour, EnteredBy;

这真的很接近,我只需要让子查询给我那个小时的总调用量,而不是一整天。

备注

  1. 我无法使用 OVER(),因为它不受最终查询可能使用的数据库引擎之一的支持。
  2. 我更愿意在 UI 中进行此类计算,但结果必须输出到电子表格中,删除该选项

如有任何建议,我们将不胜感激。

分别计算小组总数,然后合计。

SELECT 
    DATEPART(HOUR, C1.EnteredOn) AS [Hour], 
    C1.EnteredBy, 
    COUNT(*) AS CallsTaken, 
    Totals.TotalCalls, 
    CAST(COUNT(*) * 100.0 / Totals.TotalCalls AS DECIMAL(10, 2)) AS [Percentage]
FROM CallHandlingCallData AS C1
JOIN (
    SELECT DATEPART(HOUR, C2.EnteredOn) AS [Hour], COUNT(*) AS TotalCalls
    FROM CallHandlingCallData AS C2
    WHERE DATEDIFF(d, C2.EnteredOn, GetDate()) = 0
    GROUP BY DATEPART(HOUR, C2.EnteredOn)
) Totals ON Totals.[Hour] = DATEPART(HOUR, C1.EnteredOn) 
WHERE DATEDIFF(d, C1.EnteredOn, GetDate()) = 0
GROUP BY 
    DATEPART(HOUR, C1.EnteredOn), 
    C1.EnteredBy, 
    Totals.TotalCalls

如果看起来我用别名做得太过头了:我发现在消除内部和外部列引用的歧义时,安全总比后悔好得多。

如果你需要数小时内没有任何事情发生的零行,那是一个完整的'另一个带有 UNION ALL 和数字表的鱼,除非我们必须,否则我不会去那里。