# Oracle_將一欄內的多筆資料拆解 ###### tags: `oracle` `欄位拆解` ## 說明 平常可能遇到前端寫入的資料是一個欄位內有多筆的資料,也就是一個cell內的記錄是長這樣子: |column_A| column_B| |---|---| |A| 1,2,3,4,5,6,7| 而使用者希望呈現的時候是: |column_A|column_B| |---|---| |A|1| |A|2| |A|3| |A|4| |A|5| |A|6| |A|7| ## 作法 首先,弄出假資料: ```sql select 'A' column_a, '1,2,3,4,5,6,7' column_b from dual ``` 接著,將column_b的前後都加上一個`,`,並計算內含的資料筆數: ```sql select column_a, ',' || column_b || ',' column_b, -- 頭尾加上, length(column_b || ',') - length(replace(column_b, ',')) dc-- 計算裡面的資料筆數 from ( select 'A' column_a, '1,2,3,4,5,6,7' column_b from dual )a ``` 接著,利用`connect by level`設置一個範圍內的長度欄位: ```sql select * from ( select column_a, ',' || column_b || ',' column_b, -- 頭尾加上, length(column_b || ',') - length(replace(column_b, ',')) dc -- 計算裡面的資料筆數 from ( select 'A' column_a, '1,2,3,4,5,6,7' column_b from dual )a )b, -- 設置一個長度區間<=20的欄位,這部份是依實際需求所設置的長度 (select level lv from dual connect by level <=20) c where c.lv <= b.dc -- 要注意,是<=,這樣就能一口氣串出所有的資料 ``` 這時候的資料是長這樣的: |COLUMN_A| COLUMN_B| DC| LV| |---|---|---|---| |A |,1,2,3,4,5,6,7, |7 |1| |A |,1,2,3,4,5,6,7, |7 |2| |A |,1,2,3,4,5,6,7, |7 |3| |A |,1,2,3,4,5,6,7, |7 |4| |A |,1,2,3,4,5,6,7, |7 |5| |A |,1,2,3,4,5,6,7, |7 |6| |A |,1,2,3,4,5,6,7, |7 |7| 最後,再利用函數`substr`與`instr`搭配: ```sql select b.*, substr(b.column_b, -- 取值的字串來源 instr(b.column_b, ',', 1, c.lv) + 1, -- 從那開始,instr是取索引值所在位置,意思就是從b.column_b的第1個字元開始找',',然後取第c.lv個 instr(b.column_b, ',', 1, c.lv + 1) - (instr(b.column_b, ',', 1, c.lv) + 1)) split_data -- 到那裡 from ( select column_a, ',' || column_b || ',' column_b, -- 頭尾加上, length(column_b || ',') - length(replace(column_b, ',')) dc -- 計算裡面的資料筆數 from ( select 'A' column_a, '1,2,3,4,5,6,7' column_b from dual )a )b, -- 設置一個長度區間<=20的欄位,這部份是依實際需求所設置的長度,以這次的案例設置10也可以 (select level lv from dual connect by level <=20) c where c.lv <= b.dc -- 要注意,是<=,這樣就能一口氣串出所有的資料 ``` 成功將一個欄位的資料切割為多欄,如下: |COLUMN_A| COLUMN_B| DC| SPLIT_DATA| |---|---|---|---| |A| ,1,2,3,4,5,6,7,| 7| 1| |A| ,1,2,3,4,5,6,7,| 7| 2| |A| ,1,2,3,4,5,6,7,| 7| 3| |A| ,1,2,3,4,5,6,7,| 7| 4| |A| ,1,2,3,4,5,6,7,| 7| 5| |A| ,1,2,3,4,5,6,7,| 7| 6| |A| ,1,2,3,4,5,6,7,| 7| 7|