Tohle by mělo fungovat, ale je to skutečný zabiják výkonu!
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
poskytuje správné odpovědi pro vaše příkladná data. Zde je, jak to funguje:
- Nejvnitřnější část (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) vypočítá průsečík:Dva hovory se překrývají, pokud počáteční bod jednoho hovoru je v nebo za počátečním bodem druhého hovoru a na nebo před koncovým bodem tohoto hovoru - Vlastní připojení k tabulkám volání najde všechna překrytí,
- ale s problémem:Vlastní spojení najde překrytí mezi řádky 1 a 2, ale další s řádky 2 a 1. Pokud se překrývají více než dva hovory, je zdlouhavé to řešit
- Nyní, protože vaše data obsahují jedinečné číselné ID, můžeme toto použít k filtrování těchto duplikátů, triplikátů atd. To se provádí pomocí
AND a.uniqueid>b.uniqueid
selektor aGROUP BY a.uniqueid
, díky kterému budou všechna souběžná volání vidět pouze volání s nejmenším jedinečným ID, ostatní uvidí méně - Pomocí
MAX()
na tomto ve vnějším dotazu odfiltruje tento záznam - Potřebujeme
+1
získat maximální počet hovorů:Hovor se 2 souběžnými hovory znamená maximální počet 3