Celui-ci devrait fonctionner, mais c'est un véritable tueur de performances !
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
donne les bonnes réponses pour vos exemples de données. Voici comment cela fonctionne :
- La partie la plus interne (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) calcule l'intersection :deux appels se chevauchent, si le point de départ d'un appel est au niveau ou après le point de départ de l'autre appel et au niveau ou avant le point d'arrivée de cet appel - L'auto-jointure des tables d'appel trouve tous les chevauchements,
- mais avec un problème :l'auto-jointure trouve un chevauchement entre les lignes 1 et 2, mais un autre avec les lignes 2 et 1. Si plus de deux appels se chevauchent, il est fastidieux de régler ce problème
- Maintenant, puisque vos données contiennent un identifiant numérique unique, nous pouvons l'utiliser pour filtrer les doublons, les triples, etc. cela est fait par le
AND a.uniqueid>b.uniqueid
selector etGROUP BY a.uniqueid
, qui fait que seul l'appel avec le plus petit uniqueid voit tous les appels simultanés, les autres voient moins - Utiliser
MAX()
sur ceci dans la requête externe filtre cet enregistrement - Nous avons besoin du
+1
pour obtenir le nombre maximal d'appels :un appel avec 2 appels simultanés signifie un nombre maximal de 3