說明:

某一欄位中有[多筆資料,透過逗號分隔],想要將一行轉成多行,並將該欄位一筆一筆的顯示出來。

 

原始資料:

   

要轉換的結果:

   

 

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=1decode(level,1,1)

啟動例外狀況:decode如果是執行第一次則從位置1開始即可。

Level>1instr(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。

 

文章標籤
全站熱搜
創作者介紹
創作者 Nathan 的頭像
Nathan

Nathan;

Nathan 發表在 痞客邦 留言(0) 人氣(0)