¡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 yGROUP 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