Deze zou moeten werken, maar is een echte prestatiemoordenaar!
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
geeft de juiste antwoorden voor uw voorbeeldgegevens. Hier is hoe het werkt:
- Het binnenste deel (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) berekent het snijpunt:twee gesprekken overlappen elkaar, als het beginpunt van het ene gesprek op of na het beginpunt van het andere gesprek ligt en op of voor het eindpunt van dat gesprek - Zelf lid worden van de gesprekstabellen vindt alle overlappingen,
- maar met een probleem:de self-join vindt een overlapping tussen lijn 1 en 2, maar een andere met lijn 2 en 1. Als meer dan twee aanroepen elkaar overlappen, is het vervelend om dit op te lossen
- Omdat uw gegevens nu een numeriek unieke ID bevatten, kunnen we deze gebruiken om die duplicaten, drievoud enz. te filteren. Dit wordt gedaan door de
AND a.uniqueid>b.uniqueid
selector enGROUP BY a.uniqueid
, waardoor alleen de oproep met de kleinste uniqueid alle gelijktijdige oproepen ziet, de anderen minder - Gebruik
MAX()
hierover in de buitenste query filtert dit record uit - We hebben de
+1
. nodig om het piekaantal oproepen te krijgen:een oproep met 2 gelijktijdige oproepen betekent een piekaantal van 3