sql >> Base de Datos >  >> RDS >> Mysql

Consulta mysql:datos de CDR de llamadas concurrentes máximas

¡Este debería funcionar, pero es un verdadero asesino del rendimiento!

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

da las respuestas correctas para sus datos de ejemplo. Así es como funciona:

  • La parte más interna (a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate) ...) calcula la intersección:dos llamadas se superponen, si el punto inicial de una llamada está en el punto inicial de la otra llamada o después y en el punto final de esa llamada o antes
  • La unión automática de las tablas de llamadas encuentra todas las superposiciones,
  • pero con un problema:Self join encuentra una superposición entre las líneas 1 y 2, pero otra con las líneas 2 y 1. Si se superponen más de dos llamadas, es tedioso resolver esto
  • Ahora, dado que sus datos contienen una ID única numérica, podemos usarla para filtrar esos duplicados, triplicados, etc. Esto se hace con AND a.uniqueid>b.uniqueid selector y GROUP BY a.uniqueid , lo que hace que solo la llamada con el identificador único más pequeño vea todas las llamadas simultáneas, las demás vean menos
  • Usando MAX() en esto en la consulta externa filtra este registro
  • Necesitamos el +1 para obtener el conteo máximo de llamadas:una llamada con 2 llamadas simultáneas significa un conteo máximo de 3

SQLfiddle