С учетом VALUE IS NOT NULL:
with r(
id,
val,
sub_val,
len,
lvl,
flag,
rid
) as (
select id,
val,
substr(val,1,1) sub_val,
max(length(val)) over(partition by id) len,
1 lvl,
(
select count(*)
from tbl tbl2
where tbl1.id = tbl2.id
and substr(tbl1.val,1,1) = substr(tbl2.val,1,1)
and tbl1.rowid != tbl2.rowid
and rownum = 1
) flag,
rowid rid
from tbl tbl1
union all
select r.id,
r.val,
substr(r.val,1,r.lvl + 1) sub_val,
r.len,
r.lvl + 1,
(
select count(*)
from tbl
where r.id = tbl.id
and substr(r.val,1,r.lvl + 1) = substr(tbl.val,1,r.lvl + 1)
and r.rid != tbl.rowid
and rownum = 1
) flag,
r.rid
from r
where r.lvl != r.len
and flag = 1
)
select id,
sub_val
from r
where flag = 0
order by id,
sub_val
/
ID SUB_
---------- ----
1 aa
1 ab
1 c
2 aa
2 aab
2 ab
2 b
7 rows selected.
SQL>
SY.