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

时间:2017-07-05 14:42:15

标签: sql-server tsql vistadb

我需要获取当天每位用户每小时的总呼叫数,然后计算该用户接听的来电百分比。最终分析的目的是计算每用户每小时奖金的百分比。

我可以获得大部分比特,但我计算每小时的总呼叫数,即每小时组的总呼叫数... ...

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

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. 我更愿意在用户界面中进行此类计算,但结果必须输出到删除该选项的电子表格
  3. 非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

分别计算小组总数,然后将它们连接起来。

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和数字表的整个鱼壶,我不会去那里,除非我们必须。