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

लगातार दिनांक वैधता अंतराल को एक साथ जोड़ना

यह एक अंतराल और द्वीप समस्या है। इससे संपर्क करने के कई तरीके हैं; यह lead . का उपयोग करता है और lag विश्लेषणात्मक कार्य:

select distinct product,
  case when start_date is null then lag(start_date)
    over (partition by product order by rn) else start_date end as start_date,
  case when end_date is null then lead(end_date)
    over (partition by product order by rn) else end_date end as end_date
from (
  select product, start_date, end_date, rn
  from (
    select t.product,
      case when lag(end_date)
          over (partition by product order by start_date) is null
        or lag(end_date)
          over (partition by product order by start_date) != start_date - 1
        then start_date end as start_date,
      case when lead(start_date)
          over (partition by product order by start_date) is null
        or lead(start_date)
          over (partition by product order by start_date) != end_date + 1
        then end_date end as end_date,
      row_number() over (partition by product order by start_date) as rn
    from t
  )
  where start_date is not null or end_date is not null
)
order by start_date, product;

PRODUCT START_DATE END_DATE
------- ---------- ---------
A       01-JUL-13  30-SEP-13 
B       01-OCT-13  30-NOV-13 
A       01-DEC-13  31-MAR-14 

SQL Fiddle

अंतरतम क्वेरी उत्पाद के लिए पिछले और निम्नलिखित रिकॉर्ड को देखती है, और केवल प्रारंभ और/या समाप्ति समय को बरकरार रखती है यदि रिकॉर्ड सन्निहित नहीं हैं:

select t.product,
  case when lag(end_date)
      over (partition by product order by start_date) is null
    or lag(end_date)
      over (partition by product order by start_date) != start_date - 1
    then start_date end as start_date,
  case when lead(start_date)
      over (partition by product order by start_date) is null
    or lead(start_date)
      over (partition by product order by start_date) != end_date + 1
    then end_date end as end_date
from t;

PRODUCT START_DATE END_DATE
------- ---------- ---------
A       01-JUL-13            
A                            
A                  30-SEP-13 
A       01-DEC-13            
A                            
A                            
A                  31-MAR-14 
B       01-OCT-13            
B                  30-NOV-13 

चयन का अगला स्तर उन लोगों को हटा देता है जो मध्य-अवधि हैं, जहां दोनों तिथियों को आंतरिक क्वेरी द्वारा खाली कर दिया गया था, जो देता है:

PRODUCT START_DATE END_DATE
------- ---------- ---------
A       01-JUL-13            
A                  30-SEP-13 
A       01-DEC-13            
A                  31-MAR-14 
B       01-OCT-13            
B                  30-NOV-13 

बाहरी क्वेरी तब उन आसन्न जोड़े को ध्वस्त कर देती है; मैंने डुप्लीकेट बनाने और फिर उन्हें distinct . के साथ समाप्त करने के आसान मार्ग का उपयोग किया है , लेकिन आप इसे अन्य तरीकों से भी कर सकते हैं, जैसे दोनों मानों को पंक्तियों के जोड़े में से एक में रखना और दोनों मानों को दूसरे शून्य में छोड़ना, और फिर चयन की एक और परत के साथ उन्हें समाप्त करना, लेकिन मुझे लगता है कि यहां अलग ठीक है।

यदि आपके वास्तविक दुनिया के उपयोग के मामले में समय है, न कि केवल तिथियां, तो आपको आंतरिक क्वेरी में तुलना को समायोजित करने की आवश्यकता होगी; +/- 1 के बजाय, शायद 1 सेकंड का अंतराल, या यदि आप चाहें तो 1/86400, लेकिन यह आपके मूल्यों की शुद्धता पर निर्भर करता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle में महीने के नाम के बाद अनुगामी रिक्त स्थान कैसे निकालें?

  2. सिंगल टेबल के लिए मर्ज स्टेटमेंट का उपयोग करना

  3. oracle sql:यदि मौजूद है तो अपडेट करें और डालें

  4. मुझे क्या और कब setFetchSize () निर्दिष्ट करना चाहिए?

  5. जावा वर्ग से Oracle प्रक्रिया निष्पादित करते समय अवरुद्ध धागा