Oracle 如何用子行填充相同的值

Oracle 如何用子行填充相同的值,oracle,Oracle,在Oracle中,我希望将子项填充到最低的父项值。 即查询和结果 +------+------+------+------+ | col1 | col2 | col3 | col4 | +------+------+------+------+ | a | b | b | b | | a | c | c | c | | a | d | e | e | | a | d | f | f | | g

在Oracle中,我希望将子项填充到最低的父项值。
即查询和结果

+------+------+------+------+
| col1 | col2 | col3 | col4 |
+------+------+------+------+
| a    | b    | b    | b    |
| a    | c    | c    | c    |
| a    | d    | e    | e    |
| a    | d    | f    | f    |
| g    | g    | g    | g    |
| h    | i    | i    | i    |
| h    | j    | j    | j    |
+------+------+------+------+
查询: 从数据中选择col1、col2

结果:

+-----------+------+
|   col1    | col2 |
+-----------+------+
|       001 | a    |
|    001001 | b    |
|    001002 | c    |
|    001003 | d    |
| 001003001 | e    |
| 001003002 | f    |
|       002 | g    |
|       003 | h    |
|    003001 | i    |
|    003002 | j    |
+-----------+------+
col1是关键。和子索引有父索引。
我想得出这个结果

+------+------+------+------+
| col1 | col2 | col3 | col4 |
+------+------+------+------+
| a    | b    | b    | b    |
| a    | c    | c    | c    |
| a    | d    | e    | e    |
| a    | d    | f    | f    |
| g    | g    | g    | g    |
| h    | i    | i    | i    |
| h    | j    | j    | j    |
+------+------+------+------+
如果父级没有子级,子列将填充到父级。
我怎样才能得出这个结果?…
谢谢。

一种方法:

select c1, coalesce(c2, c1) c2, coalesce(c3, c2, c1) c3, coalesce(c4, c3, c2, c1) c4
  from (select substr(path, 2, 1) c1, substr(path, 4, 1) c2, 
               substr(path, 6, 1) c3, substr(path, 8, 1) c4
          from (select sys_connect_by_path(col2, ' ') path 
                  from data
                 where connect_by_isleaf = 1
               connect by substr(col1, 1, length(prior col1)) = prior col1
                   and length(prior col1) + 3 = length(col1)
                 start with length(col1) = 3 ) )
假设col2中的值是1字符长的,您可以像上面那样进行操作。否则,您必须使用
instr()
或正则表达式更改
substr(路径,…)

内部查询是分层的,我只从叶行中选择整个路径。外部查询将数据放入处理空值的特定列中。 如果您使用Oracle11g或更高版本,您可能可以使用更优雅的方式实现这一点


测试数据和输出:

create table data (col1 varchar2(10), col2 varchar2(1));
insert into data values ('001', 'a');
insert into data values ('001001', 'b');
insert into data values ('001002', 'c');
insert into data values ('001003', 'd');
insert into data values ('001003001', 'e');
insert into data values ('001003002', 'f');
insert into data values ('002', 'g');
insert into data values ('003', 'h');
insert into data values ('003001', 'i');
insert into data values ('003002', 'j');

C1 C2 C3 C4
-- -- -- --
a  b  b  b
a  c  c  c
a  d  e  e
a  d  f  f
g  g  g  g
h  i  i  i
h  j  j  j

7 rows selected