I have got the REGEXP_SUBSTR to split the semi-colon but the issue is that if there is no data between two semi-colon there the next data is shifted one column before.
Here is the below example.
Data in Oracle DB column
ColumnXYZ
A;;B
Now the my query is
SELECT REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 1) as COL1,
REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 2) as COL2,
REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 3) as COL3,
FROM TABLE T
After execution is show below data
COL1 COL2 COl3
A B null
but the I need the output in below format as between two semi-colon there is no value.
COL1 COL2 COL3
A null B
SELECT ROWNUM AS num_row,
REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', '; ;'),';;','; ;'), '[^;]+', 1, LEVEL) AS par_value
FROM dual
CONNECT BY REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', '; ;'),';;','; ;'), '[^;]+', 1, LEVEL) IS NOT NULL
Or if You need null column:
SELECT num_row,
CASE
WHEN par_value = '#$N#$' THEN NULL
ELSE par_value
END as par_value
FROM (
SELECT ROWNUM AS num_row,
REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', ';#$N#$;'),';;','; ;'), '[^;]+', 1, LEVEL) AS par_value
FROM dual
CONNECT BY
REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', ';#$N#$;'),';;','; ;'), '[^;]+', 1, LEVEL) IS NOT NULL
)
This should work:
WITH cte AS (
SELECT 'A;B;C' AS col FROM DUAL UNION
SELECT 'A;B;' AS col FROM DUAL UNION
SELECT ';B;C' AS col FROM DUAL UNION
SELECT 'A;;C' AS col FROM DUAL UNION
SELECT 'A;;' AS col FROM DUAL UNION
SELECT ';B;' AS col FROM DUAL UNION
SELECT ';;C' AS col FROM DUAL UNION
SELECT ';;' FROM DUAL
)
SELECT col
, REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 1, '', 1) AS col1
, REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 2, '', 1) AS col2
, REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 3, '', 1) AS col3
FROM cte
The pattern ([^;]*)(;|$)
matches zero or more non-semicolons followed by semicolon or end of string. Grouping is used to convert each match into two sub matches eg A;
becomes A
and ;
.
You can use replace
with '; ;'
'; ;'
argument, and then trim
with t1 as
(select replace('A;;B',';;','; ;') as str from dual
),
t2(col1,col2,col3) as
(
select regexp_substr(str, '[^;]+', 1, 1),
trim(regexp_substr(str, '[^;]+', 1, 2)),
regexp_substr(str, '[^;]+', 1, 3)
from t1
)
select * from t2;
COL1 COL2 COL3
---- ---- ----
A null B
Edit depending on your comment :
If you want row-wise result, consider the following query :
with t1 as
(select replace('A;;B',';;','; ;') as str from dual)
select trim(regexp_substr(str, '[^;]+', 1, level))
as "Result String"
from t1
cross join dual
connect by level <= length(regexp_replace(str, ';',''));
Result String
-------------
A
B
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.