Saya mengasumsikan kolom tambahan col0
yang berisi kriteria pengurutan yang jelas untuk data Anda, seperti col1
contoh data tidak benar-benar diurutkan dengan benar (berulang, mengikuti nilai A
dan E
).
Saya suka MODEL
klausul untuk tujuan semacam ini. Kueri berikut menghasilkan hasil yang diharapkan:
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)])
)
Hasil:
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
Catatan tentang klausa MODEL vs. pendekatan berbasis fungsi jendela
Meskipun hal di atas terlihat keren (atau menakutkan, tergantung pada sudut pandang Anda), Anda tentu lebih suka menggunakan pendekatan berbasis fungsi jendela seperti yang diungkapkan oleh jawaban elegan lainnya oleh nop77svk (menggunakan LAST_VALUE() IGNORE NULLS
)
atau MT0 (menggunakan LAG() IGNORE NULLS
)
. Saya telah menjelaskan jawaban ini lebih detail di posting blog ini
.