यह काम करना चाहिए, लेकिन यह एक वास्तविक प्रदर्शन हत्यारा है!
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
आपके उदाहरण डेटा के लिए सही उत्तर देता है। यह है, यह कैसे काम करता है:
- अंतरतम भाग (
a.calldate<=b.calldate AND (UNIX_TIMESTAMP(a.calldate)+a.duration)>=UNIX_TIMESTAMP(b.calldate)
...) चौराहे की गणना करता है:दो कॉल ओवरलैप होते हैं, यदि एक कॉल का शुरुआती बिंदु दूसरे कॉल के शुरुआती बिंदु पर या उसके बाद और उस कॉल के अंतिम बिंदु पर या उससे पहले होता है - कॉल टेबल में सेल्फ-जॉइनिंग सभी ओवरलैप ढूंढता है,
- लेकिन एक समस्या के साथ:सेल्फ जॉइन लाइन 1 और 2 के बीच एक ओवर लैप ढूंढता है, लेकिन दूसरा लाइन 2 और 1 के साथ। यदि दो से अधिक कॉल ओवरलैप होते हैं, तो इसे सुलझाना कठिन होता है
- अब चूंकि आपके डेटा में एक संख्यात्मक अद्वितीय आईडी है, इसलिए हम इसका उपयोग उन डुप्लिकेट, तीन प्रतियों आदि को फ़िल्टर करने के लिए कर सकते हैं। यह
AND a.uniqueid>b.uniqueid
द्वारा किया जाता है। चयनकर्ता औरGROUP BY a.uniqueid
, जो केवल सबसे छोटी यूनिकिड वाली कॉल को सभी समवर्ती कॉलों को देखता है, अन्य को कम दिखाई देता है MAX()
का उपयोग करना इस पर बाहरी क्वेरी में यह रिकॉर्ड फ़िल्टर कर देता है- हमें
+1
की आवश्यकता है अधिकतम कॉल गणना प्राप्त करने के लिए:2 समवर्ती कॉल वाली कॉल का अर्थ है 3 की अधिकतम संख्या