mysql query - peak concurrent calls CDR data

后端 未结 3 749
执笔经年
执笔经年 2021-01-14 05:50

Hi I need help working out how to calculate how many peak concurrent calls I have in a day from my CDR date stored in MySQL.

The data set looks like this:

         


        
相关标签:
3条回答
  • 2021-01-14 06:05

    Try adding +1 for each start of call, and -1 for each end, then just get cumulative sum of that +1/-1 column
    ***Convert the calldate if needed or use your format:

    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;
    
    0 讨论(0)
  • 2021-01-14 06:17

    Using Groups, have the switch write the total calls up +1 to a new CDR value for such purpose. so you know how many calls were up when the last call entered the system.

    0 讨论(0)
  • 2021-01-14 06:20

    This one should work, but is a real performance killer!

    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
    

    gives the correct answers for your example data. Here is, how it works:

    • The innermost part (a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)...) calculates the intersection: Two calls overlap, if the starting point of one call is at or after the starting point of the other call and at or before the ending point of that call
    • Self-joining the call tables finds all overlaps,
    • but with a problem: The self join finds an over lap between lines 1 and 2, but another one with lines 2 and 1. If more than two calls overlap, it is tedious to sort this out
    • Now since your data contains a numeric unique ID, we can use this to filter those duplicates, triplicates etc. this is done by the AND a.uniqueid>b.uniqueid selector and GROUP BY a.uniqueid, which makes only the call with the smallest uniqueid see all concurrent calls, the others see less
    • Using MAX() on this in the outer query filters out this record
    • We need the +1 to get the peak call count: A call with 2 concurrent calls means a peak count of 3

    SQLfiddle

    0 讨论(0)
提交回复
热议问题