Oracle資料庫9i 10g里列轉行各種方法比較

2021-09-21 16:32:56 字數 4705 閱讀 4134

把字串 '1,2,3,4,5',以逗號分隔,輸出為行,也就是 1

2345

隨手寫了乙個, oracle 10g 以上

有表如下

sql> 

select

* from

t; id name

---------- ----------------

1 0,1,5,2,8,10 

2 9,7,8 

with

vmaxnum 

as( 

select

rownum ele 

from

dual 

connect

byrownum<=(

select

max(length(

name

)-length(

replace

(name

,','

,null

)))+1 

from

t)) 

select

id, 

decode(pos,0,substr(name

,lagpos+1),substr(

name

,lagpos+1,pos-lagpos-1)) 

name

from

(select

id,name

,ele,pos,nvl(lag(pos) over (partition 

byid 

order

byele),0) lagpos 

from

(select

id,name

,ele, 

instr(name

,','

,1,ele) pos 

from

(select

/*+ all_rows no_merge(v2) use_merge(t,v2) */ 

t.id,t.name

,v2.ele 

from

t,vmaxnum v2 

where

ele<=length(

name

)-length(

replace

(name

,','

,null

))+1))) 

order

byid,ele; 

12 rows selected.

然後客戶那反饋說資料庫說9i的,報錯說connect by不能使用子查詢。

於是再稍做修改,在確定逗號不會超過99個的前提下,直接寫個常量100,可以支援9i

with

vmaxnum 

as( 

select

rownum ele 

from

dual 

connect

byrownum<=100) 

select

id, 

decode(pos,0,substr(name

,lagpos+1),substr(

name

,lagpos+1,pos-lagpos-1)) 

name

from

(select

id,name

,ele,pos,nvl(lag(pos) over (partition 

byid 

order

byele),0) lagpos 

from

(select

id,name

,ele, 

instr(name

,','

,1,ele) pos 

from

(select

/*+ all_rows no_merge(v2) use_merge(t,v2) */ 

t.*,v2.ele 

from

t,vmaxnum v2 

where

ele<=length(

name

)-length(

replace

(name

,','

,null

))+1))) 

order

byid,ele; 

後來想想這樣也不好,於是建議建立一張特定的iot表,儲存10000個數字,一般夠用了。

建立一張iot,共10000行,同樣支援9i

create table tnumber(ele,constraint pk_tnumber primary key(ele)) organization index as 

select rownum id from dual connect by rownum<

=10000; 

然後不再需要常量100,即保證準確,又保證較好的效能

create table t500 nologging as 

with   vmaxnum as ( 

select  ele 

from    tnumber 

where   ele<

=(select max(length(name)-length(replace(name,',',null)))+1 from t)) 

select id, 

decode(pos,0,substr(name,lagpos+1),substr(name,lagpos+1,pos-lagpos-1)) name 

from   (select id,name,ele,pos,nvl(lag(pos) over (partition by id order by ele),0) lagpos 

from   (select id,name,ele, 

instr(name,',',1,ele) pos 

from   (select /*+ all_rows no_merge(v2) use_merge(t,v2) */ 

t.id,t.name,v2.ele 

from   t,vmaxnum v2 

where  ele<

=length(name)-length(replace(name,',',null))+1))) 

order  by id,ele; 

12 rows selected.

下面測試一下效能:轉換50萬行試試,測試環境:dell d630 用了4年半的舊筆記本,磁碟都是碎片

sql> insert into t select rownum+4,'1,2,3,4' from dual connect by rownum<=500000;

500000 rows created.

sql> commit;

commit complete.

set timi on

sql> set timi on

sql> create table t500 nologging as

with   vmaxnum as (

select  ele

from    tnumber

where   ele<=(select max(length(name)-length(replace(name,',',null)))+1 from t))

select id,

decode(pos,0,substr(name,lagpos+1),substr(name,lagpos+1,pos-lagpos-1)) name

from   (select id,name,ele,pos,nvl(lag(pos) over (partition by id order by ele),0) lagpos

from   (select id,name,ele,

instr(name,',',1,ele) pos

from   (select /*+ all_rows no_merge(v2) use_merge(t,v2) */

t.id,t.name,v2.ele

from   t,vmaxnum v2

where  ele<=length(name)-length(replace(name,',',null))+1)))

order  by id,ele;

table created.

elapsed: 00:00:16.48

耗時16秒,含建表的寫盤時間

sql> select count(*) from t500;

count(*)

----------

2000012

當然還有別的寫法,比如簡單的可以這樣

select  id,substr(name,instr(name,',',1,rownum)+1,instr(name,',',1,rownum+1)-instr(name,',',1,rownum)-1) name 

from    (select  id,','||name||',' name from t) 

connect by rownum<

length

(translate(name,','||name,',')); 

或者10g以上用正規表示式也可以實現

這個方法可能不是最高效的,但也還可以。

這個sql的效能和字串含有的逗號的個數有關,逗號越多,也就是分隔項越多,效能越差。

oracle9i匯出oracle 10g的大字段

oracle9i匯出oracle 10g的大字段 錯誤現象 用9i的exp匯出時錯誤如下 f oracle bin exp wssw foresee cradle203 file d sb sbxx zb.dmp tables sb sbxx zb export release 9.2.0.1.0 ...

Oracle9i 10g 樹查詢特性

例子 select select id from test where level a.lv start with id a.id connect by id prior f id f id,idfrom select id,level lvfrom test connect by id fid a...

Oracle 10g資料庫管理

oracle 10g資料庫管理 課程介紹 本課程面向企業 oracle 10g 資料庫管理的學員。通過 oracle 10g 資料庫管理課程的系統培訓,使學員能夠在較短的時間內掌握 oralcle10g 資料庫管理和維護的各種技術,從而掌握最新版 oracle 的新特性和 oracle 資料通用技術...