'PL SQL String Manipulation (Deconcatenate based on multiple delimiters)
I have string such as A~B~C,D~E,F~G~H,I
. The string is comma separated and then each comma separated substring is ~
separated. There is no limit on the number of commas or ~
in a string. Objective is to get first value after each comma.
I am calling coalesce
function to fetch number of commas.
select coalesce(length('A~B~C,D~E,F~G~H,I') - length(replace('A~B~C,D~E,F~G~H,I',',',null)),
length('A~B~C,D~E,F~G~H,I'),
0) as output1
from dual;
Now, I want to run the loop for i = (output from coalesce query above) and substring the string based on comma and ~
. For example,
1st loop iteration - output = A
2nd loop iteration - output = D
3rd loop iteration - output = F
4th loop iteration - output = I
Loop Stops
I wrote this query which works fine except for the boundary cases i.e. fails in first iteration. Here i
is the i
th iteration of the loop
select substr('A~B~C,D~E,F~G~H,I',
instr('A~B~C,D~E,F~G~H,I',',',1,i) + 1,
instr('A~B~C,D~E,F~G~H,I','~',1,1)-1) as output1
from dual;
Any suggestions? Ideas?
Solution 1:[1]
The natural way to solve this problem is using Regular Expressions.
In the query below we apply expression '(^|,)[A-Z]+'
to match a letter following after the beginning of string ^
or comma ,
. So REGEXP_COUNT
lets limit the query results by exact count of matches in the string, and REGEXP_SUBSTR
extracts exactly one match for each LEVEL
from 1 to "matches count".
SELECT REGEXP_SUBSTR(T.str, '(^|,)[A-Z]+', 1, LEVEL) AS substr
FROM (
SELECT 'A~B~C,D~E,F~G~H,I' AS str FROM DUAL
) T
CONNECT BY LEVEL <= REGEXP_COUNT(T.str, '(^|,)[A-Z]+');
PS. As we see, resulting matches contain unneded commas. Not to overcomplicate the example the REPLACE(result, ',')
is omitted.
Solution 2:[2]
SELECT regexp_substr(
'UNB+UNOA,WT_Syntax_version_no+1:ZZ+2:ZZ+WT_Edi_sent_date:WT_Edi_sent_time+WT_Interchange_control_ref'
, '[^+|:|,]+'
, 1
, LEVEL
) seq_no
FROM dual
CONNECT BY regexp_substr('UNB+UNOA,WT_Syntax_version_no+1:ZZ+2:ZZ+WT_Edi_sent_date:WT_Edi_sent_time+WT_Interchange_control_ref','[^+|:]+', 1, LEVEL)
IS NOT NULL;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | diziaq |
Solution 2 | Gnqz |