如果你在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