Another solution just for fun a bit more flexible: it allows to modify column names in just one place - in the unpivot clause:
with vals as (
select/*+ materialize */
distinct
col,
val,
dense_rank()over(order by col) dr
from t
unpivot(val for col in (POS_4, POS_5, POS_6))
)
select
substr(SYS_CONNECT_BY_PATH(val,'-'),2) str
from vals
where CONNECT_BY_ISLEAF =1
start with dr=1
connect by prior dr+1=dr;
"materialize" hint there is just to workaround a bug on Oracle 19.
Full example with test data:
with t(NAME, ID, CODE, POS_4, POS_5, POS_6) as (
select 'ABC', 18, 'SAJ', 'A' , null, null from dual union all
select 'ABC', 18, 'SAJ', null, 'N' , null from dual union all
select 'ABC', 18, 'SAJ', null, 'A' , null from dual union all
select 'ABC', 18, 'SAJ', null, 'B' , null from dual union all
select 'ABC', 18, 'SAJ', null, 'F' , null from dual union all
select 'ABC', 18, 'SAJ', null, 'F' , null from dual union all
select 'ABC', 18, 'SAJ', null, null, 'H' from dual union all
select 'ABC', 18, 'SAJ', null, null, '03' from dual union all
select 'ABC', 18, 'SAJ', null, null, null from dual union all
select 'ABC', 18, 'SAJ', null, null, null from dual
)
,vals as (
select/*+ materialize */
distinct
col,
val,
dense_rank()over(order by col) dr
from t
unpivot(val for col in (POS_4, POS_5, POS_6)) -- specify columns here
)
select
substr(SYS_CONNECT_BY_PATH(val,'-'),2) str
from vals
where CONNECT_BY_ISLEAF =1
start with dr=1
connect by prior dr+1=dr;
STR
---------------
A-B-H
A-B-03
A-A-H
A-A-03
A-F-H
A-F-03
A-N-H
A-N-03