Estou assumindo uma coluna adicional
col0
que contém um critério de ordenação óbvio para seus dados, como seu col1
os dados de exemplo não estão realmente ordenados corretamente (valores repetidos e à direita de A
e E
). Eu amo o
MODEL
cláusula para este tipo de fins. A consulta a seguir produz o resultado esperado: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)])
)
Resultado:
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
SQLFiddle
Uma observação sobre a cláusula MODEL versus abordagens baseadas em função de janela
Embora o acima pareça legal (ou assustador, dependendo do seu ponto de vista), você certamente deve preferir usar uma abordagem baseada em função de janela, conforme exposto pelas outras respostas elegantes de nop77svk (usando
LAST_VALUE() IGNORE NULLS
)
ou MT0 (usando LAG() IGNORE NULLS
)
. Expliquei essas respostas com mais detalhes nesta postagem do blog
.