मैं एक अतिरिक्त कॉलम मान रहा हूँ col0
जिसमें आपके डेटा के लिए एक स्पष्ट आदेश मानदंड है, जैसे कि आपका col1
उदाहरण डेटा वास्तव में सही ढंग से ऑर्डर नहीं किया गया है (दोहराए गए, A
. के अनुगामी मान और E
)।
मुझे MODEL
पसंद है इस प्रकार के उद्देश्यों के लिए खंड। निम्नलिखित क्वेरी अपेक्षित परिणाम देती है:
WITH t(col0, col1, col2, col3, col4) AS (
SELECT 1, 'A', 0, 1, 5 FROM DUAL UNION ALL
SELECT 2, 'B', 0, 4, 0 FROM DUAL UNION ALL
SELECT 3, 'C', 2, 0, 0 FROM DUAL UNION ALL
SELECT 4, 'D', 0, 0, 0 FROM DUAL UNION ALL
SELECT 5, 'E', 3, 5, 0 FROM DUAL UNION ALL
SELECT 6, 'F', 0, 3, 0 FROM DUAL UNION ALL
SELECT 7, 'G', 0, 3, 1 FROM DUAL UNION ALL
SELECT 8, 'A', 0, 1, 5 FROM DUAL UNION ALL
SELECT 9, 'E', 3, 5, 0 FROM DUAL
)
SELECT * FROM t
MODEL
DIMENSION BY (row_number() OVER (ORDER BY col0) rn)
MEASURES (col1, col2, col3, col4)
RULES (
col2[any] = DECODE(col2[cv(rn)], 0, NVL(col2[cv(rn) - 1], 0), col2[cv(rn)]),
col3[any] = DECODE(col3[cv(rn)], 0, NVL(col3[cv(rn) - 1], 0), col3[cv(rn)]),
col4[any] = DECODE(col4[cv(rn)], 0, NVL(col4[cv(rn) - 1], 0), col4[cv(rn)])
)
परिणाम:
RN COL1 COL2 COL3 COL4
1 A 0 1 5
2 B 0 4 5
3 C 2 4 5
4 D 2 4 5
5 E 3 5 5
6 F 3 3 5
7 G 3 3 1
8 A 3 1 5
9 E 3 5 5
मॉडल क्लॉज बनाम विंडो फ़ंक्शन-आधारित दृष्टिकोण पर एक नोट
जबकि उपरोक्त अच्छा लग रहा है (या डरावना, आपके दृष्टिकोण के आधार पर), आपको निश्चित रूप से विंडो फ़ंक्शन आधारित दृष्टिकोण का उपयोग करना पसंद करना चाहिए जैसा कि अन्य सुरुचिपूर्ण उत्तरों द्वारा उजागर किया गया है nop77svk (LAST_VALUE() IGNORE NULLS
का उपयोग करके) )
या MT0 (LAG() IGNORE NULLS
का उपयोग करके) )
. मैंने इस ब्लॉग पोस्ट में इन उत्तरों के बारे में विस्तार से बताया है
।