NOTE : This post is about splitting multiple comma delimited column values in a table. If you have to apply it on a single value then look at Split single comma delimited string into rows in Oracle
In my other post I summarized various methods to split a comma delimited string into rows using Oracle SQL. However, those SQLs would only take care of a single row, i.e. when you have a single value of comma delimited string. Usually, at our work place, we deal with tables. So, this post is to demonstrate “How to split comma delimited column values in a table into multiple rows in Oracle”
Some basic setup:
SQL> DROP TABLE t PURGE;
Table dropped.
SQL> CREATE TABLE t (
2 ID NUMBER GENERATED ALWAYS AS IDENTITY,
3 text VARCHAR2(100)
4 );
Table created.
SQL> INSERT INTO t (text) VALUES ('word1, word2, word3');
1 row created.
SQL> INSERT INTO t (text) VALUES ('word4, word5, word6');
1 row created.
SQL> INSERT INTO t (text) VALUES ('word7, word8, word9');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM t;
ID TEXT
---------- ----------------------------------------------
1 word1, word2, word3
2 word4, word5, word6
3 word7, word8, word9
Now, let’s see the various methods to split the comma delimited values into rows from the table.
Using REGULAR EXPRESSIONS
INSTR in CONNECT BY clause
SQL> SELECT t.id,
2 trim(regexp_substr(t.text, '[^,]+', 1, lines.column_value)) text
3 FROM t,
4 TABLE (CAST (MULTISET
5 (SELECT LEVEL FROM dual CONNECT BY instr(t.text, ',', 1, LEVEL - 1) > 0)
6 AS sys.odciNumberList
7 )
8 ) lines
9 ORDER BY id
10 /
ID TEXT
---------- --------------------------------------------------
1 word1
1 word2
1 word3
2 word4
2 word5
2 word6
3 word7
3 word8
3 word9
9 rows selected.
SQL>
REGEXP_SUBSTR in CONNECT BY clause
SQL> SELECT t.id,
2 trim(regexp_substr(t.text, '[^,]+', 1, lines.column_value)) text
3 FROM t,
4 TABLE (CAST (MULTISET
5 (SELECT LEVEL FROM dual CONNECT BY regexp_substr(t.text , '[^,]+', 1, LEVEL) IS NOT NULL)
6 AS sys.odciNumberList
7 )
8 ) lines
9 ORDER BY id
10 /
ID TEXT
---------- --------------------------------------------------
1 word1
1 word2
1 word3
2 word4
2 word5
2 word6
3 word7
3 word8
3 word9
9 rows selected.
SQL>
REGEXP_COUNT in CONNECT BY clause
SQL> SELECT t.id,
2 trim(regexp_substr(t.text, '[^,]+', 1, lines.column_value)) text
3 FROM t,
4 TABLE (CAST (MULTISET
5 (SELECT LEVEL FROM dual CONNECT BY LEVEL <= regexp_count(t.text, ',')+1)
6 AS sys.odciNumberList
7 )
8 ) lines
9 ORDER BY id
10 /
ID TEXT
---------- --------------------------------------------------
1 word1
1 word2
1 word3
2 word4
2 word5
2 word6
3 word7
3 word8
3 word9
9 rows selected.
Using XMLTABLE
SQL> SELECT id,
2 trim(COLUMN_VALUE) text
3 FROM t,
4 xmltable(('"'
5 || REPLACE(text, ',', '","')
6 || '"'))
7 /
ID TEXT
---------- ------------------------
1 word1
1 word2
1 word3
2 word4
2 word5
2 word6
3 word7
3 word8
3 word9
9 rows selected.
SQL>
Using MODEL clause
SQL> WITH
2 model_param AS
3 (
4 SELECT id,
5 text AS orig_str ,
6 ','
7 || text
8 || ',' AS mod_str ,
9 1 AS start_pos ,
10 Length(text) AS end_pos ,
11 (Length(text) - Length(Replace(text, ','))) + 1 AS element_count ,
12 0 AS element_no ,
13 ROWNUM AS rn
14 FROM t )
15 SELECT id,
16 trim(Substr(mod_str, start_pos, end_pos-start_pos)) text
17 FROM (
18 SELECT *
19 FROM model_param MODEL PARTITION BY (id, rn, orig_str, mod_str)
20 DIMENSION BY (element_no)
21 MEASURES (start_pos, end_pos, element_count)
22 RULES ITERATE (2000)
23 UNTIL (ITERATION_NUMBER+1 = element_count[0])
24 ( start_pos[ITERATION_NUMBER+1] = instr(cv(mod_str), ',', 1, cv(element_no)) + 1,
25 end_pos[iteration_number+1] = instr(cv(mod_str), ',', 1, cv(element_no) + 1) )
26 )
27 WHERE element_no != 0
28 ORDER BY mod_str ,
29 element_no
30 /
ID TEXT
---------- --------------------------------------------------
1 word1
1 word2
1 word3
2 word4
2 word5
2 word6
3 word7
3 word8
3 word9
9 rows selected.
SQL>
Hope it helps!
Filed under: Oracle Delimited String manipulation Tagged: comma delimited values in table, comma separated column values, split column to rows, split comma delimited string, split comma delimited values in table, split comma separated column values into rows, split string
