ID |Values
-----+--------------------------------
1 |AB,AD
2 |AG, ... ,BD
3 |AV
我怎樣才能把它轉換爲:
ID |Value
-----+------
1 |AB
1 |AD
2 |AG
... |...
2 |BD
3 |AV
ID |Values
-----+--------------------------------
1 |AB,AD
2 |AG, ... ,BD
3 |AV
我怎樣才能把它轉換爲:
ID |Value
-----+------
1 |AB
1 |AD
2 |AG
... |...
2 |BD
3 |AV
使用內置的XML功能,你可以做這樣的:
with sample_data as
(
select 1 id, 'AB,AD' vals from dual union all
select 2, 'AG,AK,AJ,BA,BD' from dual union all
select 3, 'AV' from dual
)
select id, cast(t.column_value.extract('//text()') as varchar2(10)) val
from sample_data,
table(xmlsequence(xmltype(
'<x><x>' || replace(vals, ',', '</x><x>') || '</x></x>'
).extract('//x/*'))) t;
結果:
ID VAL
--- -----
1 AB
1 AD
2 AG
2 AK
2 AJ
2 BA
2 BD
3 AV
+1,XML功能非常適合這樣做。 – Ollie
使用遞歸公用表表達式,相同的查詢看起來是這樣的:
with sample_data as
(
select 1 id, 'AB,AD' vals from dual union all
select 2, 'AG,AK,AJ,BA,BD' from dual union all
select 3, 'AV' from dual
),
split_first(id, val, rem) as
(
select id,
coalesce(substr(vals, 1, instr(vals, ',') - 1), vals) val,
case when instr(vals, ',') > 0 then substr(vals, instr(vals, ',') + 1) end rem
from sample_data
union all
select id,
coalesce(substr(rem, 1, instr(rem, ',') - 1), rem) val,
case when instr(rem, ',') > 0 then substr(rem, instr(rem, ',') + 1) end rem
from split_first
where rem is not null
)
select id, val from split_first
order by id;
或者稍微不同的方法:
with sample_data as
(
select 1 id, 'AB,AD' vals from dual union all
select 2, 'AG,AK,AJ,BA,BD' from dual union all
select 3, 'AV' from dual
),
pos(id, seq, vals, sta, stp) as
(
select id, 1, vals, 1, instr(vals, ',') from sample_data
union all
select id, seq + 1, vals, stp + 1, instr(vals, ',', stp + 1) from pos
where stp > 0
)
select id, substr(vals, sta, case when stp > 0 then stp - sta else length(vals) end) from pos
order by id, seq;
我使用一個select語句 – spiaire
可怕的DB設計做到這一點,存儲分隔字符串中的值。建議您的應用程序設計者(或DBA)在插入數據庫之前分割字符串。 – Ollie
@Ollie和downvoters:這並不罕見。這實際上是一個很好的問題 –