Yang ini seharusnya bekerja, tetapi merupakan pembunuh kinerja yang nyata!
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
memberikan jawaban yang benar untuk data contoh Anda. Begini, cara kerjanya:
- Bagian terdalam (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) menghitung persimpangan:Dua panggilan tumpang tindih, jika titik awal satu panggilan berada pada atau setelah titik awal panggilan lainnya dan pada atau sebelum titik akhir panggilan tersebut - Menggabungkan sendiri tabel panggilan menemukan semua tumpang tindih,
- tetapi dengan masalah:Penggabungan diri menemukan putaran yang tumpang tindih antara baris 1 dan 2, tetapi yang lain dengan baris 2 dan 1. Jika lebih dari dua panggilan tumpang tindih, akan membosankan untuk menyelesaikannya
- Sekarang karena data Anda berisi ID unik numerik, kami dapat menggunakan ini untuk memfilter duplikat, rangkap tiga, dll. ini dilakukan oleh
AND a.uniqueid>b.uniqueid
pemilih danGROUP BY a.uniqueid
, yang hanya membuat panggilan dengan uniqueid terkecil melihat semua panggilan bersamaan, yang lain melihat lebih sedikit - Menggunakan
MAX()
tentang ini di kueri luar menyaring catatan ini - Kami membutuhkan
+1
untuk mendapatkan jumlah panggilan puncak:Panggilan dengan 2 panggilan bersamaan berarti jumlah puncak 3