Split Comma Separated Values to Columns in Oracle

Split comma separated values to columns in Oracle

You can use regexp_substr():

select regexp_substr(val, '[^,]+', 1, 1) as val1, 
regexp_substr(val, '[^,]+', 1, 2) as val2,
regexp_substr(val, '[^,]+', 1, 3) as val3,
. . .

I would suggest that you generate a column of 255 numbers in Excel (or another spreadsheet), and use the spreadsheet to generate the SQL code.

Separate comma separated string into columns oracle sql

You can use REGEXP_SUBSTR, but you must specify the number of columns.

SELECT agentname
,REGEXP_SUBSTR (categories, '[^,]+', 1, 1) AS CATA
,REGEXP_SUBSTR (categories, '[^,]+', 1, 2) AS CATB
,REGEXP_SUBSTR (categories, '[^,]+', 1, 3) AS CATC
,REGEXP_SUBSTR (categories, '[^,]+', 1, 4) AS CATD
FROM commasplit;

demo in db<>fiddle

Split comma separated values with line gaps and nulls into columns in table via pl/sql procedure

Your regular expression needs to allow for nulls, i.e. consecutive commas (but hopefully you don't have commas within any of the quoted strings...). If you have multiple source rows then it's easier to split with a recursive CTE:

with rcte (id, data, lvl, result) as (
select id, data, 1, regexp_substr(data, '(.*?)(,|$)', 1, 1, null, 1)
from disp_data
union all
select id, data, lvl + 1, regexp_substr(data, '(.*?)(,|$)', 1, lvl + 1, null, 1)
from rcte
where lvl <= regexp_count(data, ',')
)
select id, lvl, result
from rcte
order by id, lvl;

You can then pivot the result into the columns you want:

with rcte (id, data, lvl, result) as (
select id, data, 1, regexp_substr(data, '(.*?)(,|$)', 1, 1, null, 1)
from disp_data
union all
select id, data, lvl + 1, regexp_substr(data, '(.*?)(,|$)', 1, lvl + 1, null, 1)
from rcte
where lvl <= regexp_count(data, ',')
)
select *
from (
select id, lvl, result
from rcte
)
pivot (max(result) as col for (lvl) in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));

db<>fiddle

And you can use that directly in an insert statement:

insert into push_data_temp (pid,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11)
with rcte (id, data, lvl, result) as (
select id, data, 1, regexp_substr(data, '(.*?)(,|$)', 1, 1, null, 1)
from disp_data
union all
select id, data, lvl + 1, regexp_substr(data, '(.*?)(,|$)', 1, lvl + 1, null, 1)
from rcte
where lvl <= regexp_count(data, ',')
)
select *
from (
select id, lvl, result
from rcte
)
pivot (max(result) as col for (lvl) in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));

db<>fiddle

No PL/SQL needed, but you can still wrap it in a procedure if you want to.



I have to take as clob and it is throwing error as inconsistent datatype

You need to cast the tokens as varchar2, which limits their length (either 4k or 32k depending on Oracle version and settings):

with rcte (id, data, lvl, result) as (
select id, data, 1,
cast(regexp_substr(data, '(.*?)(,|$)', 1, 1, null, 1) as varchar2(4000))
from disp_data
union all
select id, data, lvl + 1,
cast(regexp_substr(data, '(.*?)(,|$)', 1, lvl + 1, null, 1) as varchar2(4000))
from rcte
where lvl <= regexp_count(data, ',')
)
...

db<>fiddle with CLOB (and connect-by examples removed, as they break it...)



when i try for text with commas in between, it splits data unevenly.

That's why I said "hopefully you don't have commas within any of the quoted strings". As you don't have any really empty elements - you have ...","","... rather than ...,,... - you can skip the concern about those I suppose, and use a different pattern:

with rcte (id, data, lvl, result) as (
select id, data, 1,
cast(regexp_substr(data, '("[^"]*"|[^,]+)', 1, 1, null, 1) as varchar2(4000))
from disp_data
union all
select id, data, lvl + 1,
cast(regexp_substr(data, '("[^"]*"|[^,]+)', 1, lvl + 1, null, 1) as varchar2(4000))
from rcte
where lvl <= regexp_count(data, '("[^"]*"|[^,]+)')
)
...

db<>fiddle

If you did have to deal with null elements then it's still possible, but more work. This also won't deal with escaped double-quotes without strings. At some point it will be easier to write your own parser in PL/SQL; or even to write the data to disk and read it back in as an external table which can handle all of this for you.

Split comma separated values into multiple rows - Oracle SQL

Here's one option; you need lines 6 onwards.

SQL> with table1 (test_type, h_level, hadoop) as
2 (select '22RETGGEDGDD, RRMMNFNEDGDD', 'Control Directory 1', 'Interchange Control Header' from dual
3 union all
4 select '22RETGGEDGDD, RRMMNFNEDGDD', 'Control Directory 2', 'Interchange Control Header' from dual
5 )
6 select trim(regexp_substr(test_type, '[^,]+', 1, column_value)) test_type,
7 h_level,
8 hadoop
9 from table1 join table(cast(multiset(select level from dual
10 connect by level <= regexp_count(test_type, ',') + 1
11 ) as sys.odcinumberlist )) on 1 = 1
12 order by 2, 1 desc, 3;

TEST_TYPE H_LEVEL HADOOP
-------------------- ------------------- --------------------------
22RETGGEDGDD Control Directory 1 Interchange Control Header
RRMMNFNEDGDD Control Directory 1 Interchange Control Header
22RETGGEDGDD Control Directory 2 Interchange Control Header
RRMMNFNEDGDD Control Directory 2 Interchange Control Header

SQL>


Related Topics



Leave a reply



Submit