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

प्रभावी लंबाई मापने के लिए समग्र अतिव्यापी खंड

मेरा मुख्य डीबीएमएस टेराडाटा है, लेकिन यह ओरेकल में भी काम करेगा।

WITH all_meas AS
 ( -- get a distinct list of all from/to points
   SELECT road_id, from_meas AS meas
   FROM road_events
   UNION
   SELECT road_id, to_meas
   FROM road_events
 )
-- select * from all_meas order by 1,2
 , all_ranges AS
 ( -- create from/to ranges
   SELECT road_id, meas AS from_meas 
     ,Lead(meas)
      Over (PARTITION BY road_id
            ORDER BY meas) AS to_meas
   FROM all_meas
  )
 -- SELECT * from all_ranges order by 1,2
, all_event_ranges AS
 ( -- now match the ranges to the event ranges
   SELECT 
      ar.*
     ,re.event_id
     ,re.year
     ,re.total_road_length
     ,ar.to_meas - ar.from_meas AS event_length
     -- used to filter the latest event as multiple events might cover the same range 
     ,Row_Number()
      Over (PARTITION BY ar.road_id, ar.from_meas
            ORDER BY year DESC) AS rn
   FROM all_ranges ar
   JOIN road_events re
     ON ar.road_id = re.road_id
    AND ar.from_meas < re.to_meas
    AND ar.to_meas > re.from_meas
   WHERE ar.to_meas IS NOT NULL
 )
SELECT event_id, road_id, year, total_road_length, Sum(event_length)
FROM all_event_ranges
WHERE rn = 1 -- latest year only
GROUP BY event_id, road_id, year, total_road_length
ORDER BY road_id, year DESC;

अगर आपको वास्तविक कवर किए गए from/to_meas . को वापस करने की आवश्यकता है (जैसा कि संपादित करने से पहले आपके प्रश्न में), यह अधिक जटिल हो सकता है। पहला भाग वही है, लेकिन एकत्रीकरण के बिना क्वेरी एक ही event_id के साथ आसन्न पंक्तियों को वापस कर सकती है (उदाहरण के लिए ईवेंट 3:0-1 और 1-25):

SELECT * FROM all_event_ranges
WHERE rn = 1
ORDER BY road_id, from_meas;

यदि आप आसन्न पंक्तियों को मर्ज करना चाहते हैं तो आपको दो और चरणों की आवश्यकता है (एक मानक दृष्टिकोण का उपयोग करके, समूह की पहली पंक्ति को ध्वजांकित करें और समूह संख्या की गणना करें):

WITH all_meas AS
 (
   SELECT road_id, from_meas AS meas
   FROM road_events
   UNION
   SELECT road_id, to_meas
   FROM road_events
 )
-- select * from all_meas order by 1,2
 , all_ranges AS
 ( 
   SELECT road_id, meas AS from_meas 
     ,Lead(meas)
      Over (PARTITION BY road_id
            ORDER BY meas) AS to_meas
   FROM all_meas
  )
-- SELECT * from all_ranges order by 1,2
, all_event_ranges AS
 (
   SELECT 
      ar.*
     ,re.event_id
     ,re.year
     ,re.total_road_length
     ,ar.to_meas - ar.from_meas AS event_length
     ,Row_Number()
      Over (PARTITION BY ar.road_id, ar.from_meas
            ORDER BY year DESC) AS rn
   FROM all_ranges ar
   JOIN road_events  re
     ON ar.road_id = re.road_id
    AND ar.from_meas < re.to_meas
    AND ar.to_meas > re.from_meas
   WHERE ar.to_meas IS NOT NULL
 )
-- SELECT * FROM all_event_ranges WHERE rn = 1 ORDER BY road_id, from_meas
, adjacent_events AS 
 ( -- assign 1 to the 1st row of an event
   SELECT t.*
     ,CASE WHEN Lag(event_id)
                Over(PARTITION BY road_id
                     ORDER BY from_meas) = event_id
           THEN 0 
           ELSE 1 
      END AS flag
   FROM all_event_ranges t
   WHERE rn = 1
 )
-- SELECT * FROM adjacent_events ORDER BY road_id, from_meas 
, grouped_events AS
 ( -- assign a groupnumber to adjacent rows using a Cumulative Sum over 0/1
   SELECT t.*
     ,Sum(flag)
      Over (PARTITION BY road_id
            ORDER BY from_meas
            ROWS Unbounded Preceding) AS grp
   FROM adjacent_events t
)
-- SELECT * FROM grouped_events ORDER BY  road_id, from_meas
SELECT event_id, road_id, year, Min(from_meas), Max(to_meas), total_road_length, Sum(event_length)
FROM grouped_events
GROUP BY event_id, road_id, grp, year, total_road_length
ORDER BY 2, Min(from_meas);

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

ठीक है, मुझे अभी एक ब्लॉग मिला है प्राथमिकता के साथ ओवरलैपिंग रेंज कुछ सरलीकृत Oracle सिंटैक्स के साथ बिल्कुल वैसा ही करना। वास्तव में मैंने अपनी क्वेरी को टेराडाटा में कुछ अन्य सरलीकृत वाक्यविन्यास से मानक/ओरेकल एसक्यूएल :-)

में अनुवादित किया है

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-01795:एक सूची में अभिव्यक्तियों की अधिकतम संख्या 1000 है, स्ट्रिंग को कैसे विभाजित करें

  2. R12.2 अपग्रेड पार्ट -2 (R12.2.0 के लिए मुख्य अपग्रेड ड्राइवर) में चरण दर चरण अपग्रेड प्रक्रिया

  3. तालिका उत्परिवर्तन त्रुटियों से कैसे बचें

  4. तालिका नाम और संबंधित गिनती सूचीबद्ध करने के लिए ओरेकल प्रक्रिया

  5. Oracle 10g एक तिथि में 5 अंकों का वर्ष स्वीकार करता है