create Table TestTable as
select 1 as Code,1 as ID,'A' as Val from dual
union all select 1,1,'x' from dual
union all select 1,1,'A' from dual
union all select 1,1,'x' from dual
union all select 1,1,'A' from dual
union all select 1,1,'A' from dual
union all select 1,1,'A' from dual
union all select 1,2,'B' from dual
union all select 1,2,'B' from dual
union all select 1,2,'B' from dual
union all select 1,2,'x' from dual
union all select 1,2,'B' from dual
union all select 1,2,'x' from dual
union all select 1,3,'A' from dual
union all select 1,3,'A' from dual
union all select 1,3,'K' from dual
union all select 1,3,'A' from dual
union all select 1,3,'A' from dual
union all select 1,3,'A' from dual
union all select 1,4,'C' from dual
union all select 1,4,'C' from dual
union all select 1,4,'x' from dual
union all select 1,4,'C' from dual
union all select 1,4,'C' from dual
union all select 1,4,'x' from dual
union all select 1,4,'C' from dual
union all select 1,5,'D' from dual
union all select 1,5,'B' from dual
union all select 1,5,'D' from dual
union all select 1,5,'D' from dual
union all select 1,5,'D' from dual
union all select 1,6,'E' from dual
union all select 1,6,'F' from dual
union all select 1,6,'E' from dual
union all select 1,6,'M' from dual
union all select 1,6,'E' from dual
union all select 1,7,'L' from dual
union all select 1,7,'F' from dual
union all select 1,7,'F' from dual
union all select 1,8,'G' from dual
union all select 1,8,'G' from dual
union all select 1,8,'G' from dual
union all select 1,8,'G' from dual
union all select 1,8,'G' from dual
union all select 1,8,'G' from dual
union all select 2,1,'R' from dual
union all select 2,1,'x' from dual
union all select 2,1,'R' from dual
union all select 2,1,'x' from dual
union all select 2,1,'R' from dual
union all select 2,1,'R' from dual
union all select 2,1,'R' from dual
union all select 2,2,'T' from dual
union all select 2,2,'Z' from dual
union all select 2,2,'T' from dual
union all select 2,2,'x' from dual
union all select 2,2,'T' from dual
union all select 2,2,'x' from dual
union all select 2,3,'R' from dual
union all select 2,3,'R' from dual
union all select 2,3,'K' from dual
union all select 2,3,'R' from dual
union all select 2,3,'R' from dual
union all select 2,3,'R' from dual
union all select 2,4,'C' from dual
union all select 2,4,'C' from dual
union all select 2,4,'x' from dual
union all select 2,4,'C' from dual
union all select 2,4,'C' from dual
union all select 2,4,'x' from dual
union all select 2,4,'C' from dual
union all select 2,5,'W' from dual
union all select 2,5,'T' from dual
union all select 2,5,'W' from dual
union all select 2,5,'W' from dual
union all select 2,5,'W' from dual
union all select 2,6,'P' from dual
union all select 2,6,'P' from dual
union all select 2,6,'P' from dual
union all select 2,6,'P' from dual
union all select 2,6,'P' from dual
union all select 2,7,'L' from dual
union all select 2,7,'F' from dual
union all select 2,7,'F' from dual
union all select 2,8,'G' from dual
union all select 2,8,'G' from dual
union all select 2,8,'G' from dual
union all select 2,8,'G' from dual
union all select 2,8,'G' from dual
union all select 2,8,'G' from dual;
col Code for 9999
col ID for 99
col Val for a4
col Var for a20
--■■■Connect_by_IsLeafを使う方法(10g以降)■■■
select Code,ID,
decode(Level,1,Val,'Var') as Val,
case when Level >= 2
then SubStr(sys_connect_by_path(ValCount,','),2) end as Var
from (select Code,ID,Val,
to_char(count(*)) || 'x' || Val as ValCount,
Row_Number() over(partition by Code,ID order by count(*) desc,Val) as Rank
from TestTable
where Val != 'x'
group by Code,ID,Val)
where Connect_by_IsLeaf = 1
Start With Rank = 1
connect by prior Code = Code
and prior ID = ID
and prior Rank = Rank-1
order by Code,ID;
--■■■Connect_by_IsLeafを使わない方法■■■
select Code,ID,
decode(Level,1,Val,'Var') as Val,
case when Level >= 2
then SubStr(sys_connect_by_path(ValCount,','),2) end as Var
from (select Code,ID,Val,
to_char(count(*)) || 'x' || Val as ValCount,
Row_Number() over(partition by Code,ID order by count(*) desc,Val) as Rank,
count(*) over(partition by Code,ID) as MaxLevel
from TestTable
where Val != 'x'
group by Code,ID,Val)
where Level = MaxLevel
Start With Rank = 1
connect by prior Code = Code
and prior ID = ID
and prior Rank = Rank-1
order by Code,ID;