說明:
某一欄位中有[多筆資料,透過逗號分隔],想要將一行轉成多行,並將該欄位一筆一筆的顯示出來。
原始資料:
要轉換的結果:
SQL:
select USERID,
substr(GID||',',
decode(level,1,1,instr(GID||',',',',1,level-1)+1),
decode(level,1,instr(GID||',',',',1,level)-1,instr(GID||',',',',1,level) - instr(GID||',',',',1,level-1)-1) ) as GID_S
,'|||' " "
,decode(level,1,1,instr(GID||',',',',1,level-1)+1) A01_該群組的起始位置
,decode(level,1,1,instr(GID||',',',',1,level) - instr(GID||',',',',1,level-1)-1) A02_該群組的字串長度
,level 層級
from
(
select 'ID' USERID
,'XMLP_TEMPLATE_DESIGNER,XMLP_ANALYZER_ONLINE,XMLP_ADMIN,XMLP_ANALYZER_EXCEL,XMLP_SCHEDULER' GID
from dual
) connect by instr(GID||',',',',1,level)>0
order by level
從整段字串中,每次擷取需使用的字串。
substr(GID||',',decode(level,1,1,instr(GID||',',',',1,level-1)+1),decode(level,1,instr(GID||',',',',1,level)-1,instr(GID||',',',',1,level) - instr(GID||',',',',1,level-1)-1) ) as GID_S
這部分可以拆成三部分來看:
抓取GID該字串的某個區間,從A01這個位置當起始點,往後抓取至第A02該長度的位置。
假設A01是10,A02代表15,則代表從第10個位置開始當起始點,然後抓取10+15該區間內的資料,也就是字串中10~25位置的文字。
substr(GID||',',A01,A02)
根據Level該數字判斷計算要抓取字串的起始點
Level=1:decode(level,1,1)
啟動例外狀況:decode如果是執行第一次則從位置1開始即可。
Level>1:instr(GID||',',',',1,level-1)+1
根據Level該數字,判斷要抓取字串中第幾個逗號。
抓取字串的起始點
A01:decode(level,1,1,instr(GID||',',',',1,level-1)+1) A01_該群組的起始位置
抓取字串的長度
A02:decode(level,1,1,instr(GID||',',',',1,level) - instr(GID||',',',',1,level-1)-1) A02_該群組的字串長度
判斷GID這個字串有幾個逗號(包含自己在字尾新增的逗號),則代表要執行幾次遞迴,
每執行一次則代表會產生一行新資料。
而每執行一次Level+1,假設全部資料有6個逗號,則Level到第七次時,instr抓不到第7個逗號則回傳負數,此時就離開遞迴。
connect by instr(GID||',',',',1,level)>0
本篇SQL語法參考:yelang9809 提供的解決方案。
[范例] 请教Oracle数据问题一行转换为多行
http://www.itpub.net/thread-1129639-1-1.html
Oracle數據庫Decode函數的使用方法
http://blog.itcert.org/archives/902
DECODE(control_value,value1,result1[,value2,result2…][,default_result]);
select decode( x , 1 , ‘x is 1 ‘, 2 , ‘x is 2 ‘, ‘others’) from dual
當x等於1時,則返回‘x is 1’。
當x等於2時,則返回‘x is 2’。
oracle instr()函数用法详解
http://www.111cn.net/database/Oracle/41242.htm
instr( string1, string2 [, start_po(www.111cn.net)sition [, nth_appearance ] ] )
string1是要搜索的字符串。
string2为string1中搜索子串。
start_position是string1中搜索将开始的位置。此参数是可选。如果省略,则默认为1。字符串中的第一个位置是1。如果start_position是负数,函数从string1的开(www.111cn.net)始搜索字符串,然后对结束计数的字符数start_position。
nth_appearance string2的第n个外观。这是可选的。如果省略,则默认为1。
注意:
如果string2在string1中找到,然后INSTR Oracle函数将返回0。
