如果你在11g或更高,你可以UNPIVOT的列行,这“失去”的空值,同时跟踪它们的原始顺序:
select customername, addr,
row_number() over (partition by customername order by colnum) as rn
from test
unpivot (addr for colnum in (add1 as 1, add2 as 2, add3 as 3, add4 as 4))
CUSTOMERNAME ADDR RN
------------ ---- ----------
JEMMY 1 1
JEMMY No 2
JEMMY 2 3
JEREMY No 1
JEREMY 1 2
JOCKY 1 1
...
,然后转动,早:
select *
from (
select customername, addr,
row_number() over (partition by customername order by colnum) as rn
from test
unpivot (addr for colnum in (add1 as 1, add2 as 2, add3 as 3, add4 as 4))
)
pivot (max(addr) as addr for (rn) in (1 as a, 2 as b, 3 as c, 4 as d))
演示的CTE为您的样本数据,和重命名枢列回原来的名字:
with test (CUSTOMERNAME, ADD1, ADD2, ADD3, ADD4) as (
select cast('JONY' as varchar2(12)), cast(NULL as varchar2(4)),
cast('No' as varchar2(4)), cast('No' as varchar2(4)), cast('1' as varchar2(4))
from dual
union all select 'JEMMY', '1', NULL, 'No', '2' from dual
union all select 'JOOJOO', '1', 'No', 'No', '3' from dual
union all select 'JEREMY', NULL, NULL, 'No', '1' from dual
union all select 'JOCKY', '1', 'No', NULL, '2' from dual
union all select 'Jack', '1', 'No', 'No', NULL from dual
)
select customername, a_addr as add1, b_addr as add2, c_addr as add3, d_addr as add4
from (
select customername, addr,
row_number() over (partition by customername order by colnum) as rn
from test
unpivot (addr for colnum in (add1 as 1, add2 as 2, add3 as 3, add4 as 4))
)
pivot (max(addr) as addr for (rn) in (1 as a, 2 as b, 3 as c, 4 as d))
order by customername;
CUSTOMERNAME ADD1 ADD2 ADD3 ADD4
------------ ---- ---- ---- ----
JEMMY 1 No 2
JEREMY No 1
JOCKY 1 No 2
JONY No No 1
JOOJOO 1 No No 3
Jack 1 No No
这可能比Aleksej的做法比较昂贵,但它是值得考虑的选择,你可以随时评估两者(和拿出其他人)看看哪个数据最适合你。
看起来像一个非常糟糕的桌子设计。 –
是的,但这是要求:) –
一个PL/SQL块更适合于实现你想要做的事情 – GurV