sql >> Databasteknik >  >> RDS >> Mysql

mysql-fråga - topp samtidiga samtal CDR-data

Den här borde fungera, men är en riktig prestationsdödare!

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

ger rätt svar för dina exempeldata. Så här fungerar det:

  • Den innersta delen (a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate) ...) beräknar skärningspunkten:Två samtal överlappar varandra, om startpunkten för ett samtal är vid eller efter startpunkten för det andra samtalet och vid eller före slutpunkten för det samtalet
  • Om du själv går med i samtalstabellerna hittar du alla överlappningar,
  • men med ett problem:Självanslutningen hittar ett övervarv mellan rad 1 och 2, men en annan med rad 2 och 1. Om fler än två samtal överlappar är det tråkigt att reda ut detta
  • Nu eftersom din data innehåller ett numeriskt unikt ID kan vi använda detta för att filtrera dessa dubbletter, triplikat etc. detta görs av AND a.uniqueid>b.uniqueid selector och GROUP BY a.uniqueid , vilket gör att bara samtalet med den minsta unika ID ser alla samtidiga samtal, de andra ser mindre
  • Med MAX() på detta i den yttre frågan filtrerar bort denna post
  • Vi behöver +1 för att få maxantalet samtal:Ett samtal med 2 samtidiga samtal innebär en peak count på 3

SQLfiddle



  1. Det gick inte att ansluta till SQL Server från Linux

  2. Välj utan FRÅN men med fler än en rad

  3. .nextval JDBC-infogningsproblem

  4. PHP MYSQL:sätt att lista tabellen i stigande ordning