您好我需要帮助解决如何计算我存储在MySQL中的CDR日期中一天内有多少峰值并发呼叫。
数据集如下所示:
INSERT INTO `cdr` (`calldate`, `clid`, `src`, `dst`, `dcontext`, `channel`, `dstchannel`,
`lastapp`, `lastdata`, `duration`, `billsec`, `disposition`, `amaflags`,
`accountcode`, `uniqueid`, `userfield`) VALUES
我可以使用以下查询来计算每个唯一日期的条目数。
SELECT COUNT(1) AS entries, date(calldate) AS DATE
FROM `cdr`
GROUP BY DATE (calldate)
LIMIT 0 , 1000
然而,这只能告诉我并发呼叫的理论峰值而不是实际峰值。
要获得实际的峰值,我们需要先了解每次通话的开始和结束日期和时间。 当前开始日期和时间记录在(校准)字段中,并且呼叫的持续时间以秒为单位记录在(持续时间)字段中。通过将(持续时间)字段中存储的秒数添加到(calldate)字段,我们可以计算完成时间。
现在我们知道开始和结束时间,我们需要计算这些时间是否重叠以及重复多少次。这种级别的SQL查询远远超出我的知识。
总结一下,我试图用MySQL查询计算同时调用的峰值数来自MySQL中存储的CDR数据。感谢任何帮助
示例数据:
calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield
08/11/2013 17:02,x,x,1000,default,x,x,x,x,26,26,ANSWERED,3,x,1383930162,x
08/11/2013 17:02,x,x,1000,default,x,x,x,x,24,24,ANSWERED,3,x,1383930164,x
08/11/2013 17:02,x,x,1000,default,x,x,x,x,45,45,ANSWERED,3,x,1383930146,x
08/11/2013 17:10,x,x,1000,default,x,x,x,x,2,2,ANSWERED,3,x,1383930649,x
08/11/2013 17:22,x,x,1000,default,x,x,x,x,4,4,ANSWERED,3,x,1383931380,x
08/11/2013 17:23,x,x,1000,default,x,x,x,x,5,5,ANSWERED,3,x,1383931388,x
08/11/2013 17:23,x,x,1000,default,x,x,x,x,9,9,ANSWERED,3,x,1383931395,x
10/11/2013 09:28,x,x,1000,default,x,x,x,x,7,7,ANSWERED,3,x,1384075689,x
10/11/2013 10:09,x,x,1000,default,x,x,x,x,57,57,ANSWERED,3,x,1384078181,x
10/11/2013 10:09,x,x,1000,default,x,x,x,x,81,81,ANSWERED,3,x,1384078164,x
10/11/2013 10:09,x,x,1000,default,x,x,x,x,102,102,ANSWERED,3,x,1384078143,x
11/11/2013 10:23,x,x,1000,default,x,x,x,x,3,3,ANSWERED,3,x,1384165439,x
11/11/2013 17:46,x,x,1000,default,x,x,x,x,30,30,ANSWERED,3,x,1384191975,x
11/11/2013 17:46,x,x,1000,default,x,x,x,x,30,30,ANSWERED,3,x,1384191976,x
11/11/2013 17:45,x,x,1000,default,x,x,x,x,50,50,ANSWERED,3,x,1384191956,x
11/11/2013 17:55,x,x,1000,default,x,x,x,x,9,9,ANSWERED,3,x,1384192544,x
13/11/2013 10:59,x,x,1000,default,x,x,x,x,209,209,ANSWERED,3,x,1384340382,x
13/11/2013 10:59,x,x,1000,default,x,x,x,x,230,230,ANSWERED,3,x,1384340361,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1342,1342,ANSWERED,3,x,1384340963,x
13/11/2013 11:10,x,x,1000,default,x,x,x,x,1312,1312,ANSWERED,3,x,1384341009,x
13/11/2013 11:08,x,x,1000,default,x,x,x,x,1441,1441,ANSWERED,3,x,1384340891,x
13/11/2013 11:10,x,x,1000,default,x,x,x,x,1288,1288,ANSWERED,3,x,1384341059,x
13/11/2013 11:10,x,x,1000,default,x,x,x,x,1306,1306,ANSWERED,3,x,1384341050,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1378,1378,ANSWERED,3,x,1384340990,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1419,1419,ANSWERED,3,x,1384340953,x
13/11/2013 11:06,x,x,1000,default,x,x,x,x,1558,1558,ANSWERED,3,x,1384340815,x
13/11/2013 11:12,x,x,1000,default,x,x,x,x,1254,1254,ANSWERED,3,x,1384341121,x
13/11/2013 11:10,x,x,1000,default,x,x,x,x,1330,1330,ANSWERED,3,x,1384341045,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1431,1431,ANSWERED,3,x,1384340947,x
13/11/2013 11:11,x,x,1000,default,x,x,x,x,1302,1302,ANSWERED,3,x,1384341076,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1383,1383,ANSWERED,3,x,1384340995,x
13/11/2013 11:08,x,x,1000,default,x,x,x,x,1444,1444,ANSWERED,3,x,1384340937,x
13/11/2013 11:07,x,x,1000,default,x,x,x,x,1531,1531,ANSWERED,3,x,1384340850,x
13/11/2013 11:09,x,x,1000,default,x,x,x,x,1418,1418,ANSWERED,3,x,1384340963,x
13/11/2013 12:02,x,x,1000,default,x,x,x,x,10,10,ANSWERED,3,x,1384344169,x
13/11/2013 12:01,x,x,1000,default,x,x,x,x,807,807,ANSWERED,3,x,1384344072,x
13/11/2013 12:03,x,x,1000,default,x,x,x,x,680,680,ANSWERED,3,x,1384344200,x
13/11/2013 12:01,x,x,1000,default,x,x,x,x,793,793,ANSWERED,3,x,1384344090,x
13/11/2013 12:01,x,x,1000,default,x,x,x,x,772,772,ANSWERED,3,x,1384344111,x
答案 0 :(得分:3)
这个应该有效,但是真正的性能杀手!
SELECT
calldate,
MAX(concurrent)+1 AS peakcount
FROM (
SELECT
DATE(a.calldate) as calldate,
COUNT(b.uniqueid) AS concurrent
FROM cdr AS a, cdr AS b
WHERE
a.calldate BETWEEN '2013-11-08 00:00:00' AND '2013-11-13 23:59:59'
AND (
(a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate))
OR (b.calldate<=a.calldate AND (UNIX_TIMESTAMP(b.calldate)+b.duration)>=UNIX_TIMESTAMP(a.calldate))
)
AND a.uniqueid>b.uniqueid
GROUP BY a.uniqueid
) AS baseview
GROUP BY calldate
为您的示例数据提供正确的答案。这是它的工作原理:
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...)计算交集:如果一个呼叫的起点位于另一个呼叫的起始点或之后,并且在结束点或之前,则两个呼叫重叠。那个电话AND a.uniqueid>b.uniqueid
选择器和GROUP BY a.uniqueid
完成,这只会使用最小的uniqueid查看所有并发呼叫,其他人看不到MAX()
过滤掉此记录+1
来获取峰值呼叫计数:具有2个并发呼叫的呼叫意味着峰值计数为3 答案 1 :(得分:1)
尝试为每个调用开始添加+1,为每个结尾添加-1,然后获取该+ 1 / -1列的累积总和
***如果需要,转换calldate或使用您的格式:
set @from:='2015-02-01';
set @to:='2015-03-01';
set @csum:=0;
SELECT DT,CallCount, (@csum := @csum + CallCount) as cumulative_sum
FROM
(select calldate AS DT, 1 AS CallCount
from cdr
where calldate between @from and @to
union all
select ADDDATE(calldate,INTERVAL duration SECOND) AS DT, -1 AS CallCount
from cdr
where calldate between @from and @to
) Calls
ORDER BY 1 asc;
答案 2 :(得分:0)
使用群组,让交换机将总呼叫+1写入新的CDR值以实现此目的。所以你知道最后一次呼叫进入系统时有多少通话。