Sql server 使用条件对列进行计数,根据计数分配值

Sql server 使用条件对列进行计数,根据计数分配值,sql-server,tsql,Sql Server,Tsql,我有一张有通话记录的桌子。我需要为下一次通话分配时间段,根据在哪个时间段可以找到电话号码 该表的相关列为: 电话号码|呼叫时间戳 CallTimeStamp是一个datetime对象 我需要计算以下各项: 时隙:根据时间戳,我需要计算每个电话号码的每个时隙(例如0800-1000、1001-1200等)的计数。现在,如果某个特定时隙的计数大于“n”,那么我需要将该时隙分配给该数字。否则,我选择一个默认的时间段 工作日时段:与上面相同,但与工作日相同 优先级:基本上是一个数字达到多少次的计数

我有一张有通话记录的桌子。我需要为下一次通话分配时间段,根据在哪个时间段可以找到电话号码

该表的相关列为:

电话号码|呼叫时间戳

CallTimeStamp是一个datetime对象

我需要计算以下各项:

  • 时隙:根据时间戳,我需要计算每个电话号码的每个时隙(例如0800-1000、1001-1200等)的计数。现在,如果某个特定时隙的计数大于“n”,那么我需要将该时隙分配给该数字。否则,我选择一个默认的时间段
  • 工作日时段:与上面相同,但与工作日相同
  • 优先级:基本上是一个数字达到多少次的计数
以下是我为解决这些问题所做的努力:

优先 计算一个电话号码被呼叫的次数是很简单的。如果通话记录中有一个号码,我知道它被呼叫了。在这种情况下,下面的查询将为我提供每个号码的呼叫计数

SELECT DISTINCT(PhoneNumber), COUNT(PhoneNumber) FROM tblCallLog
GROUP BY PhoneNumber
但是,我的问题是,我需要根据该列本身的值更改字段Count(PhoneNumber)中的值。我该如何实现这一目标?(例如,如果Count(PhoneNumber)给我的值大于20,我需要将其更改为5)

时段/工作日 这就是我完全困惑的地方,我正在寻找“数据库”的工作方式

不幸的是,我无法摆脱反复思考的过程。例如,如果我正在聚合某个电话号码(如“123456”)和某个时间段(如0800-1000小时),我可以编写如下查询:

DECLARE @T1Start time = '08:00:00.0000'
DECLARE @T2End time = '10:00:00.0000'

SELECT COUNT(CallTimeStamp) FROM tblCallLog 
WHERE PhoneNumber = '123456' AND FORMAT(CallTimeStamp, 'hh:mm:ss') >= @T1Start AND FORMAT(CallTimeStamp, 'hh:mm:ss') < @T2End
DECLARE@T1Start time='08:00:00.0000'
声明@T2End time='10:00:00.0000'
从tblCallLog中选择COUNT(CallTimeStamp)
其中PhoneNumber='123456'和FORMAT(CallTimeStamp,'hh:mm:ss')>=@T1Start和FORMAT(CallTimeStamp,'hh:mm:ss')<@T2End
现在,我可以检查表中每个不同的电话号码,计算每个时隙的值,然后为电话号码分配一个时隙值。但是,必须有一种方法不需要我迭代数据库

因此,我正在寻找如何解决这个问题的建议


谢谢

您可以使用DATEPART函数获取周-日时段。 要计算时间段,您可以尝试将一天开始的分钟数除以时间段的大小。它将返回您的插槽号。您可以使用CASE语句将其转换为适当的字符串,也可以使用look表存储插槽描述

选择
电话号码
,DATEPART(WEEKDAY,l.CallTimeStamp)作为DayOfWeekSlot
,DATEDIFF(分钟,CONVERT(DATE,l.CallTimeStamp),l.CallTimeStamp)/120作为TwoHourSlot/*您可以更改分钟数以获得不同的插槽大小*/
,COUNT(*)作为计数
从tblCallLog l
按电话号码分组
,DATEPART(工作日,l.CallTimeStamp)
,DATEDIFF(分钟,转换(日期,l.CallTimeStamp),l.CallTimeStamp)/120

您可以尝试返回电话号码、一周中的哪一天以及2小时的时间段。如果呼叫量大于20,则该值设置为5(不确定为什么设置为5?)。2小时部分的代码是根据这个问题改编的,其中(24/2)中的值2是时间段中的小时数

SELECT  
      PhoneNumber
    , DATENAME(weekday,CallTimeStamp) as [day]
    , CONVERT(smalldatetime,ROUND(CAST(CallTimeStamp as float) * (24/2),0)/(24/2)) AS RoundedTime
    , CASE WHEN COUNT(*) > 20 THEN 5 ELSE COUNT(*) END
FROM 
      tblCallLog
GROUP BY      
      PhoneNumber
    , DATENAME(weekday,dateadd(s,start_ts,'01/01/1970'))

谢谢,我修改了tblCallLog来存储DayOfWeekSlot和TwoHourSlot以及CallTimeStamp(感谢您的查询),因为这些值是经常需要的,所以存储它们也是有意义的。