Mysql
 sql >> Base de données >  >> RDS >> Mysql

requête mysql - pic d'appels simultanés données CDR

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 et GROUP 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 

SQLfiddle