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

जब बार-बार संसाधित किए जा सकने वाले आइटम के लिए ऑफ़सेट परिवर्तनशील होता है, तो मैं "अगला" ईवेंट कैसे प्राप्त करूं?

यह एक अंतराल और द्वीप समस्या है, लेकिन द्वीपों को REQ . द्वारा परिभाषित किया जा रहा है लेन-देन इसे कुछ की तुलना में थोड़ा अधिक जटिल बनाता है।

आपको जो चाहिए वह प्राप्त करने के लिए आप नेस्टेड लीड और लैग फ़ंक्शंस और कुछ हेरफेर का उपयोग कर सकते हैं:

select distinct item,
  coalesce(start_tran,
    lag(start_tran) over (partition by item order by timestamp)) as start_tran,
  coalesce(end_tran,
    lead(end_tran) over (partition by item order by timestamp)) as end_tran,
  coalesce(end_time, 
    lead(end_time) over (partition by item order by timestamp))
    - coalesce(start_time,
        lag(start_time) over (partition by item order by timestamp)) as time
from (
  select item, timestamp, start_tran, start_time, end_tran, end_time
  from (
    select item,
      timestamp,
      case when lag_tran is null or transaction like 'REQ%'
        then transaction end as start_tran,
      case when lag_tran is null or transaction like 'REQ%'
        then timestamp end as start_time,
      case when lead_tran is null or lead_tran like 'REQ%'
        then transaction end as end_tran,
      case when lead_tran is null or lead_tran like 'REQ%'
        then timestamp end as end_time
    from (
      select item, transaction, timestamp,
        lag(transaction)
          over (partition by item order by timestamp) as lag_tran,
        lead(transaction)
          over (partition by item order by timestamp) as lead_tran
      from transactions
    )
  )
  where start_tran is not null or end_tran is not null
)
order by item, start_tran;

आइटम 1 और 2 के लिए दूसरे चक्र के लिए अतिरिक्त रिकॉर्ड के साथ जो दे सकता है:

      ITEM START_TRAN END_TRAN   TIME      
---------- ---------- ---------- -----------
         1 REQ-A      PICKUP     0 1:53:30.0 
         1 REQ-E      PICKUP     0 1:23:30.0 
         2 REQ-B      MAIL       0 0:24:13.0 
         2 REQ-F      REQ-F      0 0:0:0.0   
         3 REQ-C      PICKUP     0 1:46:30.0 
         4 REQ-D      PULL       0 0:23:59.0 
         5 REQ-A      PICKUP     0 1:43:59.0 

SQL Fiddle सभी मध्यवर्ती चरण दिखा रहा है।

यह उतना डरावना नहीं है जितना पहली नज़र में लग सकता है। अंतरतम क्वेरी कच्चा डेटा लेती है और लीड और लैग लेनदेन के लिए एक अतिरिक्त कॉलम जोड़ती है। आइटम-1 रिकॉर्ड का केवल पहला सेट लेना जो होगा:

      ITEM TRANSACTION TIMESTAMP                LAG_TRAN   LEAD_TRAN
---------- ----------- ------------------------ ---------- ----------
         1 REQ-A       2014-07-31T09:51:32Z                PULL       
         1 PULL        2014-07-31T10:22:21Z     REQ-A      TRANSFER   
         1 TRANSFER    2014-07-31T10:22:23Z     PULL       ARRIVE     
         1 ARRIVE      2014-07-31T11:45:01Z     TRANSFER   PICKUP     
         1 PICKUP      2014-07-31T11:45:02Z     ARRIVE     REQ-E      

नोटिस REQ-E अंतिम lead_tran . के रूप में पॉप अप हो रहा है ? यह पहला transaction है इस मद के लिए रिकॉर्ड के दूसरे चक्र के लिए, और बाद में उपयोगी होने जा रहा है। क्वेरी का अगला स्तर उन लीड और लैग मानों का उपयोग करता है और REQ . का व्यवहार करता है प्रारंभ और अंत मार्कर के रूप में मान, और उस जानकारी का उपयोग प्रत्येक चक्र के पहले और अंतिम रिकॉर्ड को छोड़कर सब कुछ रद्द करने के लिए करता है।

      ITEM TIMESTAMP                START_TRAN START_TIME               END_TRAN   END_TIME               
---------- ------------------------ ---------- ------------------------ ---------- ------------------------
         1 2014-07-31T09:51:32Z     REQ-A      2014-07-31T09:51:32Z                                         
         1 2014-07-31T10:22:21Z                                                                             
         1 2014-07-31T10:22:23Z                                                                             
         1 2014-07-31T11:45:01Z                                                                             
         1 2014-07-31T11:45:02Z                                         PICKUP     2014-07-31T11:45:02Z     

क्वेरी का अगला स्तर उन पंक्तियों को हटा देता है जो प्रारंभ या अंत का प्रतिनिधित्व नहीं कर रही हैं (या दोनों - देखें REQ-F Fiddle में) क्योंकि हमें उनमें कोई दिलचस्पी नहीं है:

      ITEM TIMESTAMP                START_TRAN START_TIME               END_TRAN   END_TIME               
---------- ------------------------ ---------- ------------------------ ---------- ------------------------
         1 2014-07-31T09:51:32Z     REQ-A      2014-07-31T09:51:32Z                                         
         1 2014-07-31T11:45:02Z                                         PICKUP     2014-07-31T11:45:02Z     

अब हमारे पास प्रत्येक चक्र के लिए पंक्तियों के जोड़े हैं (या REQ-F . के लिए एक पंक्ति ) अंतिम स्तर रिक्त स्थान को भरने के लिए फिर से सीसा और अंतराल का उपयोग करता है; अगर start_tran शून्य है तो यह एक अंत-पंक्ति है और हमें पिछली पंक्ति के प्रारंभ डेटा का उपयोग करना चाहिए; अगर end_tran शून्य है तो यह एक प्रारंभ-पंक्ति है और हमें अगली पंक्ति के अंतिम डेटा का उपयोग करना चाहिए।

  ITEM START_TRAN START_TIME               END_TRAN   END_TIME                 TIME      
     1 REQ-A      2014-07-31T09:51:32Z     PICKUP     2014-07-31T11:45:02Z     0 1:53:30.0 
     1 REQ-A      2014-07-31T09:51:32Z     PICKUP     2014-07-31T11:45:02Z     0 1:53:30.0 

यह दोनों पंक्तियों को समान बनाता है, इसलिए distinct डुप्लिकेट हटा देता है।



  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 त्रुटि ORA-06512

  2. तालिका को अद्यतन करने के लिए Oracle फ़ंक्शन, यदि रिकॉर्ड शून्य है तो INSERT

  3. Oracle में CLOB को BLOB में कैसे बदलें?

  4. औसत समय अंतराल कैसे करें?

  5. C# को Oracle डेटाबेस से जोड़ने के लिए आवश्यक न्यूनतम क्लाइंट फुटप्रिंट क्या है?