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 undGROUP 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