How to split column value in Oracle sql - sql

How to split a column value which is not having space or any other delimiter. I searched the forums but I couldn't able to find the solution for my scenario.
Here is my scenario
ID Column_Value
011 abcdefgh
The result should be
Column_Value1 Column_Value2
abcd efgh

Assuming you just want to split a column down the middle, you can achieve this with a combination of substr and length:
SELECT SUBSTR(column_value, 1, LENGTH(column_value) / 2),
SUBSTR(column_value, LENGTH(column_value) / 2 + 1)
FROM mytable
SQLFiddle

If you want to split the string based on the length and number of characters, then use SUBSTR as follows:
SQL> with data(str) as(
2 select 'abcdefgh' from dual
3 )
4 select substr(str, 1, 4) col1,
5 substr(str, length(substr(str, 1, 4)) +1) col2
6 from data;
COL1 COL2
---- ----
abcd efgh
SQL>
Above, you could change the value of 4 to your desired value. Remember, both are not mutually exclusive.

Related

Display all the names of the employees whose names having letter A as 2nd occurrence without using like operator

For the above query, I am using regexp_count but in SQL command line I am getting regexp_count :invaild identifier;
select * from table_name WHERE (REGEXP_COUNT(column_name, 'A')) >2;
Is this query works?
I'm not sure what you really want; is it to return names whose 2nd letter is "a", or names that have two or more letters "a" within.
Anyway, pick the one you find appropriate.
SQL> create table test as
2 (select 'saritha' col from dual union all
3 select 'mamatha' from dual union all
4 select 'vaisnavi' from dual union all
5 select 'sai' from dual union all
6 select 'vijaya' from dual union all
7 select 'kumar' from dual
8 );
Table created.
2 or more letters "a":
SQL> select col
2 from test
3 where regexp_count(col, 'a') >= 2;
COL
--------
saritha
mamatha
vaisnavi
vijaya
2nd letter is "a":
SQL> select col
2 from test
3 where substr(col, 2, 1) = 'a';
COL
--------
saritha
mamatha
vaisnavi
sai
SQL>
On Oracle 10g, which doesn't support REGEXP_COUNT function, one option is to replace all letters a with an empty string (basically, you'd remove all letters a) and fetch rows whose difference of full column length and "replaced" column length is >= 2. Something like this:
SQL> select col
2 from test
3 where length(col) - length(replace(col, 'a', '')) >= 2;
COL
--------
saritha
mamatha
vaisnavi
vijaya
SQL>

SQL Sub string Right char index

input
-----------
'12345-123'
'3456-67'
output
-----------
column 1 column 2
12345 123
3456 67
In SQL For Column 1 :
SELECT Substring('12345-123',1,CHARINDEX('-','12345-123')-1)
For column 2 : unable to achieve ? can any one help me
a simple way to accomplish both columns using reverse(), keeps the logic identical.
SELECT Substring('12345-123',1,CHARINDEX('-','12345-123')-1) col1, reverse(Substring(reverse('12345-123'),1,CHARINDEX('-',reverse('12345-123'))-1)) col2
Well, you can use string manipulation:
select left(input, charindex('-', input) - 1) as col1,
stuff(input, 1, charindex('-', input), '') as col2
from t;
Here is a db<>fiddle.

Oracle : SQL to replace items in a string with items of another string

I have a column "col1" value like : 'a,b,x,y,z' (ordered string)
Another column "col2" is like : 'a,x' or 'b,y,z' (ordered string)
All the string values in "col2" are generated by a subquery. So it is not constant.
But, the value in "col1" is constant. That is col1='a,b,x,y,z'
create table test (col1 varchar2(20), col2 varchar2(10));
insert into test values ('a,b,x,y,z','a,x');
insert into test values ('a,b,x,y,z','b,y,z');
Need help with the replacing in one sql.
Need help to replace the elements on "col1" with "col2".
For example,
when col2='a,x', the result should be : 'b,y,z'
when col2='b,y,z', the result should be : 'a,x'
Here is a fun way to do this:
select col1, col2,
ltrim(regexp_replace(translate(replace(col1,','),','||replace(col2,','),',')
,'(.)',',\1'),',') as col3
from test;
That is: (reading the function calls as they are executed, from inside out)
Remove the commas from both strings
Use TRANSLATE() to remove the characters of the second string from the first string
Use REGEXP_REPLACE to add commas before each character of the remaining string
Trim the leading comma
Here's one option; I included the ID column to make it simpler. I hope that a column similar to it exists in your real case.
The idea is:
split each column (col1, col2) to rows
CTE one represents col1's rows
CTE two represents col2's rows
using the MINUS set operator, subtract those two sets of rows
using LISTAGG, aggregate the result
SQL> select * From test;
ID COL1 COL2
---------- -------------------- ----------
1 a,b,x,y,z a,x
2 a,b,x,y,z b,y,z
SQL> with
2 one as
3 (select id, regexp_substr(col1, '[^,]+', 1, column_value) col
4 from test,
5 table(cast(multiset(select level from dual
6 connect by level <= regexp_count(col1, ',') + 1
7 ) as sys.odcinumberlist))
8 ),
9 two as
10 (select id, regexp_substr(col2, '[^,]+', 1, column_value) col
11 from test,
12 table(cast(multiset(select level from dual
13 connect by level <= regexp_count(col2, ',') + 1
14 ) as sys.odcinumberlist))
15 ),
16 t_minus as
17 (select id, col from one
18 minus
19 select id, col from two
20 )
21 select id, listagg(col, ',') within group (order by col) result
22 From t_minus
23 group by id;
ID RESULT
---------- --------------------
1 b,y,z
2 a,x
SQL>

Replace a column value in a string delimiter using Oracle SQL

I have a string value in a column in a table like
001|3880000005376|Personal ID| ||15-MAY-2006
and I want to replace the fourth value by another string value 'ABCDEF' , can it be possible by a single update or by PL/SQL program?
Here's one option:
SQL> with test (id, col) as
2 (select 1, '001|3880000005376|Personal ID| ||15-MAY-2006' from dual union all
3 select 2, '002|3880000005376|Personal ID|XXX||15-MAY-2007' from dual
4 )
5 select
6 id,
7 regexp_replace(col, '[^|]+', 'NEW STRING', 1, 4) result
8 from test;
ID RESULT
---------- ------------------------------------------------------------
1 001|3880000005376|Personal ID|NEW STRING||15-MAY-2006
2 002|3880000005376|Personal ID|NEW STRING||15-MAY-2007
SQL>
It replaces 4th occurrence of the '[^|]+' pattern with a NEW STRING value.

Comma-separated string match

I have this query:
SELECT regexp_replace (var_called_num, '^' ||ROUTING_PREFIX) INTO Num
FROM INCOMING_ROUTING_PREFIX
WHERE var_called_num LIKE ROUTING_PREFIX ||'%';`
INCOMING_ROUTING_PREFIX table has two rows
1) 007743
2) 007742
var_called_num is 0077438843212123. So above query gives the result 8843212123.
So basically, the query is removing prefix (longest match from table) from var_called_num.
Now my table has changed. Now it has only 1 row which is comma-separated.
Modified Table:
INCOMING_ROUTING_PREFIX table has one row which is comma-separated:
1) 007743,007742
How to modify the query to achieve the same behavior. Need to remove longest match prefix from var_called_num.
Here's one option: you'd have to split the prefix into rows, and the use it in REGEXP_REPLACE.
SQL> with
2 calnum (var_called_num) as
3 (select '0077438843212123' from dual),
4 incoming_routing_prefix (routing_prefix) as
5 (select '007743,007742' from dual),
6 --
7 irp_split as
8 (select regexp_substr(i.routing_prefix, '[^,]+', 1, level) routing_prefix
9 from incoming_routing_prefix i
10 connect by level <= regexp_count(i.routing_prefix, ',') + 1
11 )
12 select regexp_replace(c.var_called_num, '^' || s.routing_prefix) result
13 from calnum c join irp_split s on s.routing_prefix = substr(c.var_called_num, 1, length(s.routing_prefix));
RESULT
----------------
8843212123
SQL>
By the way, why did you change the model to a worse version than it was before?
you can split the values
with test as (
select regexp_substr('007743,007742','[^,]+', 1, level) as ROUTING_PREFIX from dual
connect by regexp_substr('007743,007742S', '[^,]+', 1, level) is not null
)
and that use the view in your select
SELECT regexp_replace ('0077438843212123', '^' ||ROUTING_PREFIX)
FROM test WHERE '0077438843212123' LIKE ROUTING_PREFIX ||'%';