Jag antar en extra kolumn col0
som innehåller uppenbara ordningskriterier för dina data, som din col1
exempeldata är inte riktigt ordnade (upprepade, efterföljande värden för A
och E
).
Jag älskar MODEL
klausul för dessa typer av ändamål. Följande fråga ger det förväntade resultatet:
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)])
)
Resultat:
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
En notering om MODEL-satsen kontra fönsterfunktionsbaserade tillvägagångssätt
Även om ovanstående ser coolt ut (eller läskigt, beroende på din synvinkel), bör du verkligen föredra att använda en fönsterfunktionsbaserad metod som avslöjas av de andra eleganta svaren av nop77svk (med LAST_VALUE() IGNORE NULLS
)
eller MT0 (med LAG() IGNORE NULLS
)
. Jag har förklarat dessa svar mer i detalj i det här blogginlägget
.