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

अतिव्यापी दिनांक अवधि के साथ MySQL समेकित तालिका पंक्तियाँ

ऐसा करने का एक तरीका सहसंबद्ध उपश्रेणियों का उपयोग करना है:

SELECT DISTINCT
       (SELECT MIN(opens)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS start,
       (SELECT MAX(closes)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS end       
FROM mytable AS t1
ORDER BY opens

WHERE सहसंबद्ध उपश्रेणियों की विधेय:

t2.opens <= t1.closes AND t2.closes >= t1.opens

वर्तमान रिकॉर्ड से संबंधित सभी अतिव्यापी रिकॉर्ड लौटाएं। इन रिकॉर्डों को एकत्र करने से हम प्रत्येक अंतराल की शुरुआत / समाप्ति तिथियां पा सकते हैं:अंतराल की शुरुआत की तारीख न्यूनतम opens है सभी अतिव्यापी रिकॉर्ड के बीच की तारीख, जबकि अंतिम तिथि अधिकतम closes है तारीख।

यहां डेमो करें

संपादित करें:

उपरोक्त समाधान निम्न जैसे अंतरालों के सेट के साथ काम नहीं करेगा:

1. |-----------|
2. |----|
3.           |-----|

रिकॉर्ड नं। 2, संसाधित होने पर, एक त्रुटिपूर्ण प्रारंभ/समाप्ति अंतराल उत्पन्न करेगा।

यहां वेरिएबल का उपयोग करके समाधान दिया गया है:

SELECT MIN(start) AS start, MAX(end) AS end
FROM (
  SELECT @grp := IF(@start = '1900-01-01' OR 
                   (opens <= @end AND closes >= @start), @grp, @grp+1) AS grp,        
         @start := IF(@start = '1900-01-01', opens, 
                      IF(opens <= @end AND closes >= @start, 
                         IF (@start < opens, @start, opens), opens)) AS start,
         @end := IF(@end = '1900-01-01', closes, 
                    IF (opens <= @end AND closes >= @start, 
                      IF (@end > closes, @end, closes), closes)) AS end                 
  FROM mytable
  CROSS JOIN (SELECT @grp := 1, @start := '1900-01-01', @end := '1900-01-01') AS vars
  ORDER BY opens, DATEDIFF(closes, opens) DESC) AS t
GROUP BY grp

विचार सबसे बाईं ओर से शुरू करना है opens/closes मध्यान्तर। चर @start , @end वृद्धिशील रूप से विस्तार करने के लिए उपयोग किया जाता है (जैसा कि नई ओवरलैपिंग पंक्तियों को संसाधित किया जा रहा है) समेकित अंतराल अंतराल श्रृंखला के नीचे। एक बार गैर-अतिव्यापी अंतराल का सामना करने के बाद, [@start - @end] इस नए अंतराल और grp . से मेल खाने के लिए इनिशियलाइज़ किया गया है एक से बढ़ा दिया गया है।

यहां डेमो करें




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL में नो-रो दिनों में प्रति दिन पंक्तियों की संख्या कैसे समूहित करें?

  2. PDO का उपयोग करके तालिका में बड़ी मात्रा में चर सम्मिलित करें

  3. mysqli_fetch_row, mysqli_fetch_object, mysqli_fetch_assoc, mysqli_fetch_array का उपयोग कब और क्यों करें

  4. डबल पोर्ट के कारण पीएचपी पीडीओ आरंभीकरण विफल - ध्यान में न आया PDOException:SQLSTATE [HY000] [2002]

  5. सरणी PHP->JSON->XCODE में सरणियों का विश्लेषण कैसे करें?