Denne burde virke, men er en rigtig præstationsdræber!
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
giver de rigtige svar til dine eksempeldata. Sådan fungerer det:
- Den inderste del (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) beregner skæringspunktet:To opkald overlapper hinanden, hvis startpunktet for et opkald er ved eller efter startpunktet for det andet opkald og ved eller før slutpunktet for det opkald - Hvis du selv tilslutter dig opkaldstabellerne, finder du alle overlapninger,
- men med et problem:Selvforbindelsen finder en overlapning mellem linje 1 og 2, men en anden med linje 2 og 1. Hvis mere end to opkald overlapper, er det trættende at ordne dette
- Da dine data nu indeholder et numerisk unikt ID, kan vi bruge dette til at filtrere disse dubletter, triplikater osv. dette gøres ved hjælp af
AND a.uniqueid>b.uniqueid
selector ogGROUP BY a.uniqueid
, hvilket får kun opkaldet med det mindste unikke id til at se alle samtidige opkald, de andre ser færre - Ved brug af
MAX()
på dette i den ydre forespørgsel frafiltrerer denne post - Vi har brug for
+1
for at få det maksimale antal opkald:Et opkald med 2 samtidige opkald betyder et maksimalt tal på 3