Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

समय के बीच डेटाबेस में एक साथ घटनाओं का पता लगाना

अस्वीकरण:मैं अपना उत्तर निम्नलिखित (उत्कृष्ट) पोस्ट के आधार पर लिख रहा हूँ:

https://www.itprotoday.com/sql-server/calculating-concurrent-sessions-part-3 (भाग 1 और 2 की भी सिफारिश की जाती है)

उस समस्या के साथ यहां समझने वाली पहली बात यह है कि इंटरनेट में पाए जाने वाले अधिकांश मौजूदा समाधानों में मूल रूप से दो मुद्दे हो सकते हैं

  • परिणाम सही उत्तर नहीं है (उदाहरण के लिए यदि श्रेणी ए, बी और सी के साथ ओवरलैप होती है लेकिन बी सी के साथ ओवरलैप नहीं होती है तो वे 3 ओवरलैपिंग रेंज के रूप में गिना जाता है)।
  • इसकी गणना करने का तरीका बहुत अक्षम है (क्योंकि O(n^2) है और / या वे इस अवधि में प्रत्येक सेकंड के लिए चक्कर लगाते हैं)

समाधान में सामान्य प्रदर्शन समस्या, जैसे कि अनरेसन्स द्वारा प्रस्तावित, एक कुदरती समाधान है, प्रत्येक कॉल के लिए आपको अन्य सभी कॉलों की जांच करनी होगी यदि वे ओवरलैप हैं।

एक एल्गोरिथम रैखिक सामान्य समाधान है जो सभी "घटनाओं" (प्रारंभ कॉल और समाप्ति कॉल) को सूचीबद्ध करता है, और एक शुरुआत के लिए 1 जोड़ें और हैंग-अप के लिए 1 को घटाएं, और अधिकतम याद रखें। इसे कर्सर के साथ आसानी से कार्यान्वित किया जा सकता है (हाफोर द्वारा प्रस्तावित समाधान उस तरह से प्रतीत होता है) लेकिन कर्सर समस्याओं को हल करने के सबसे प्रभावी तरीके नहीं हैं।

संदर्भित लेख में उत्कृष्ट उदाहरण, विभिन्न समाधान, उनके प्रदर्शन की तुलना है। प्रस्तावित समाधान है:

WITH C1 AS
(
  SELECT starttime AS ts, +1 AS TYPE,
    ROW_NUMBER() OVER(ORDER BY starttime) AS start_ordinal
  FROM Calls

  UNION ALL

  SELECT endtime, -1, NULL
  FROM Calls
),
C2 AS
(
  SELECT *,
    ROW_NUMBER() OVER(  ORDER BY ts, TYPE) AS start_or_end_ordinal
  FROM C1
)
SELECT MAX(2 * start_ordinal - start_or_end_ordinal) AS mx
FROM C2
WHERE TYPE = 1

स्पष्टीकरण

मान लीजिए डेटा का यह सेट

+-------------------------+-------------------------+
|        starttime        |         endtime         |
+-------------------------+-------------------------+
| 2009-01-01 00:02:10.000 | 2009-01-01 00:05:24.000 |
| 2009-01-01 00:02:19.000 | 2009-01-01 00:02:35.000 |
| 2009-01-01 00:02:57.000 | 2009-01-01 00:04:04.000 |
| 2009-01-01 00:04:12.000 | 2009-01-01 00:04:52.000 |
+-------------------------+-------------------------+

यह एक प्रश्न के साथ एक ही विचार को लागू करने का एक तरीका है, कॉल की प्रत्येक शुरुआत के लिए 1 जोड़ना और प्रत्येक समाप्ति के लिए 1 घटाना।

  SELECT starttime AS ts, +1 AS TYPE,
    ROW_NUMBER() OVER(ORDER BY starttime) AS start_ordinal
  FROM Calls

C1 CTE का यह भाग प्रत्येक कॉल का प्रत्येक प्रारंभ समय लेगा और इसे नंबर देगा

+-------------------------+------+---------------+
|           ts            | TYPE | start_ordinal |
+-------------------------+------+---------------+
| 2009-01-01 00:02:10.000 |    1 |             1 |
| 2009-01-01 00:02:19.000 |    1 |             2 |
| 2009-01-01 00:02:57.000 |    1 |             3 |
| 2009-01-01 00:04:12.000 |    1 |             4 |
+-------------------------+------+---------------+

अब यह कोड

  SELECT endtime, -1, NULL
  FROM Calls

पंक्ति क्रमांकन के बिना सभी "अंतिम समय" उत्पन्न करेगा

+-------------------------+----+------+
|         endtime         |    |      |
+-------------------------+----+------+
| 2009-01-01 00:02:35.000 | -1 | NULL |
| 2009-01-01 00:04:04.000 | -1 | NULL |
| 2009-01-01 00:04:52.000 | -1 | NULL |
| 2009-01-01 00:05:24.000 | -1 | NULL |
+-------------------------+----+------+

अब यूनियन को पूर्ण C1 CTE परिभाषा बनाने के लिए, आपके पास दोनों टेबल मिश्रित होंगे

+-------------------------+------+---------------+
|           ts            | TYPE | start_ordinal |
+-------------------------+------+---------------+
| 2009-01-01 00:02:10.000 |    1 |             1 |
| 2009-01-01 00:02:19.000 |    1 |             2 |
| 2009-01-01 00:02:57.000 |    1 |             3 |
| 2009-01-01 00:04:12.000 |    1 |             4 |
| 2009-01-01 00:02:35.000 | -1   |     NULL      |
| 2009-01-01 00:04:04.000 | -1   |     NULL      |
| 2009-01-01 00:04:52.000 | -1   |     NULL      |
| 2009-01-01 00:05:24.000 | -1   |     NULL      |
+-------------------------+------+---------------+

C2 की गणना एक नए कॉलम के साथ C1 को क्रमबद्ध और क्रमांकित करने के लिए की जाती है

C2 AS
(
  SELECT *,
    ROW_NUMBER() OVER(  ORDER BY ts, TYPE) AS start_or_end_ordinal
  FROM C1
)

+-------------------------+------+-------+--------------+
|           ts            | TYPE | start | start_or_end |
+-------------------------+------+-------+--------------+
| 2009-01-01 00:02:10.000 |    1 | 1     |            1 |
| 2009-01-01 00:02:19.000 |    1 | 2     |            2 |
| 2009-01-01 00:02:35.000 |   -1 | NULL  |            3 |
| 2009-01-01 00:02:57.000 |    1 | 3     |            4 |
| 2009-01-01 00:04:04.000 |   -1 | NULL  |            5 |
| 2009-01-01 00:04:12.000 |    1 | 4     |            6 |
| 2009-01-01 00:04:52.000 |   -1 | NULL  |            7 |
| 2009-01-01 00:05:24.000 |   -1 | NULL  |            8 |
+-------------------------+------+-------+--------------+

और वह जगह है जहां जादू होता है, किसी भी समय #start - #ends का परिणाम इस समय सहवर्ती कॉल की मात्रा है।

प्रत्येक प्रकार =1 (प्रारंभ घटना) के लिए हमारे पास तीसरे कॉलम में #start मान है। और हमारे पास #start + #end (चौथे कॉलम में)

. भी है
#start_or_end = #start + #end

#end = (#start_or_end - #start)

#start - #end = #start - (#start_or_end - #start)

#start - #end = 2 * #start - #start_or_end

तो SQL में:

SELECT MAX(2 * start_ordinal - start_or_end_ordinal) AS mx
FROM C2
WHERE TYPE = 1

इस मामले में कॉल के प्रस्तावित सेट के साथ, परिणाम 2 है।

प्रस्तावित लेख में, उदाहरण के लिए एक सेवा या "फोन कंपनी" या "फोन सेंट्रल" द्वारा समूहीकृत परिणाम प्राप्त करने के लिए थोड़ा सुधार किया गया है और इस विचार का उपयोग समूह के लिए भी किया जा सकता है उदाहरण के लिए समय स्लॉट द्वारा और अधिकतम समरूपता है किसी दिए गए दिन में घंटे के हिसाब से।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कॉलम नाम उत्पन्न करने के लिए गतिशील एसक्यूएल?

  2. JDBC का उपयोग करके संग्रहीत कार्यविधि से *सब कुछ* वापस कैसे प्राप्त करें

  3. एमएस एसक्यूएल सर्वर में संचयी कुल

  4. SQL सर्वर एजेंट शेड्यूल संशोधित करें (T-SQL)

  5. SQL सर्वर प्रबंधन स्टूडियो (SSMS) - SQL सर्वर / TSQL ट्यूटोरियल भाग 14 में एक साथ कई क्वेरी और परिणाम कैसे देखें