Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Abfrage - CDR-Daten für gleichzeitige Spitzenanrufe

Dieser sollte funktionieren, ist aber ein echter 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

gibt die richtigen Antworten für Ihre Beispieldaten. So funktioniert es:

  • Der innerste Teil (a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate) ...) berechnet den Schnittpunkt:Zwei Calls überschneiden sich, wenn der Startpunkt des einen Calls am oder nach dem Startpunkt des anderen Calls und am oder vor dem Endpunkt des Calls liegt
  • Selbstverknüpfung der Anruftabellen findet alle Überschneidungen,
  • aber mit einem Problem:Der Selbstbeitritt findet eine Überschneidung zwischen den Leitungen 1 und 2, aber eine andere mit den Leitungen 2 und 1. Wenn sich mehr als zwei Anrufe überschneiden, ist es mühsam, dies zu klären
  • Da Ihre Daten nun eine eindeutige numerische ID enthalten, können wir diese verwenden, um diese Duplikate, Dreifach-IDs usw. zu filtern. Dies geschieht durch AND a.uniqueid>b.uniqueid Selektor und GROUP BY a.uniqueid , wodurch nur der Aufruf mit der kleinsten eindeutigen ID alle gleichzeitigen Aufrufe sieht, die anderen sehen weniger
  • Mit MAX() darauf in der äußeren Abfrage diesen Datensatz herausfiltert
  • Wir brauchen den +1 So ermitteln Sie die maximale Anrufanzahl:Ein Anruf mit 2 gleichzeitigen Anrufen bedeutet eine maximale Anzahl von 3

SQLfiddle