Substring between characters in Oracle 9i - sql

In later versions I can use this regexp_substr:
SELECT
ID,
regexp_substr(ID, '[^.]+', 1, 2) DATA 1,
regexp_substr(ID, '[^.]+', 1, 3) DATA 2
FROM employees
Table: Employees
ID
--------------------------
2017.1.3001-ABC.01.01
2017.2.3002-ABCD.02.02
2017.303.3003-ABC.03.03
2017.404.3004-ABCD.04.04
Expected output:
ID DATA 1 DATA 2
------------------------ ------ ---------
2017.1.3001-ABC.01.01 1 3001-ABC
2017.2.3002-ABCD.02.02 2 3002-ABCD
2017.303.3003-ABC.03.03 303 3003-ABC
2017.404.3004-ABCD.04.04 404 3004-ABCD
Please help me to get the sub-string between . characters in ID column in SQL Oracle 9i.

You don't need regular expressions - just use SUBSTR and INSTR:
SELECT id,
SUBSTR( id, dot1 + 1, dot2 - dot1 - 1) AS data1,
SUBSTR( id, dot2 + 1, dot3 - dot2 - 1) AS data2
FROM (
SELECT id,
INSTR( id, '.', 1, 1 ) AS dot1,
INSTR( id, '.', 1, 2 ) AS dot2,
INSTR( id, '.', 1, 3 ) AS dot3
FROM employees
);

Related

extract data sql

Example: Below is the string(sentence) in field and I want to extract the specific data from the below patterns using select query in different fields:
i )
Input :
/a03/infor/current/server/infa_sh/ScriptFil/infa_common/adap_main 'FI_RE_PRJ' 'wf_RE_ACC_TIE_HIS_MNT_EN_AM'
Output :
Select query to fetch FI_RE_PRJ and wf_RE_ACC_TIE_HIS_MNT_EN_AM
Other pattern I have is :
Input :
$SCRIPTS/run_in.ksh -f FI_FLE_PRJ -wait wf_FI_SV_CNCL_RP_BAS_KF
Output :
Select query to fetch FI_FLE_PRJ and wf_FI_SV_CNCL_RP_BAS_KF from input
We can try using REGEXP_SUBSTR with a capture group:
SELECT
REGEXP_SUBSTR(col, '''(.*?)''', 1, 1, NULL, 1) AS first,
REGEXP_SUBSTR(col, '''(.*?)''', 1, 2, NULL, 1) AS second
FROM yourTable;
You can use simple string functions (which are much faster than regular expressions):
SELECT SUBSTR( value, pos1 + 1, pos2 - pos1 - 1 ) AS quote1,
SUBSTR( value, pos3 + 1, pos4 - pos3 - 1 ) AS quote2
FROM (
SELECT value,
INSTR(value, '''', 1, 1) AS pos1,
INSTR(value, '''', 1, 2) AS pos2,
INSTR(value, '''', 1, 3) AS pos3,
INSTR(value, '''', 1, 4) AS pos4
FROM table_name
)
Which, for the sample data:
CREATE TABLE table_name (value) AS
SELECT '/a03/infor/current/server/infa_sh/ScriptFil/infa_common/adap_main ''FI_RE_PRJ'' ''wf_RE_ACC_TIE_HIS_MNT_EN_AM''' FROM DUAL;
Outputs:
QUOTE1
QUOTE2
FI_RE_PRJ
wf_RE_ACC_TIE_HIS_MNT_EN_AM
fiddle

I need to Update my row with english version

I have a column which includes rows like this : MER.Fiyatlandırma Müdür Yardımcısı.
SELECT name, SUBSTR(
name,
INSTR(name, '.', 1, 1),
INSTR(name, '.', 1, 2) + 1 - INSTR(name, '.', 1, 1)
) AS deneme
FROM HR_ALL_POSITIONS_F;
I used this code and my rows looks like .Fiyatlandırma Müdür Yardımcısı.
Also ı have an excel file which includes .Fiyatlandırma Müdür Yardımcısı. this row and english version.
I need to change .Fiyatlandırma Müdür Yardımcısı. this to Price Vice Manager.
How can ı do that.
UPDATE denememusa123
SET denememusa123.eklenecekkolon = (SELECT ENGLISHPOSITION FROM pozisyontanimlama)
WHERE (SELECT SUBSTR (name,
INSTR (name,
'.',
1,
1),
INSTR (name,
'.',
1,
2)
+ 1
- INSTR (name,
'.',
1,
1))
FROM HR_ALL_POSITIONS_F) = (Select TURKISHPOSITION FROM pozisyontanimlama);
(I tired this but it is not working.
ora-01427:single-row subquery returns more than one row )
Help Please.
You can use a MERGE statement:
MERGE INTO denememusa123 dst
USING (
WITH split_denememusa123 (rid, prefix, position, suffix) AS (
SELECT rowid AS rid,
SUBSTR(
eklenecekkolon,
1,
INSTR(eklenecekkolon, '.', 1, 1)
) AS prefix,
SUBSTR(
eklenecekkolon,
INSTR(eklenecekkolon, '.', 1, 1) + 1,
INSTR(eklenecekkolon, '.', 1, 2) - INSTR(eklenecekkolon, '.', 1, 1) - 1
) AS position,
SUBSTR(
eklenecekkolon,
INSTR(eklenecekkolon, '.', 1, 2)
) AS suffix
FROM denememusa123
WHERE INSTR(eklenecekkolon, '.', 1, 2) > 0
)
SELECT s.rid, s.prefix || p.englishposition || s.suffix AS position
FROM split_denememusa123 s
INNER JOIN pozisyontanimlama p
ON (p.turkishposition = s.position)
) src
ON (src.rid = dst.ROWID)
WHEN MATCHED THEN
UPDATE SET dst.eklenecekkolon = src.position;
Which, for the sample data:
CREATE TABLE denememusa123 (eklenecekkolon) AS
SELECT 'MER.Fiyatlandırma Müdür Yardımcısı.XYZ' FROM DUAL;
CREATE TABLE pozisyontanimlama (turkishposition, englishposition) AS
SELECT 'Fiyatlandırma Müdür Yardımcısı', 'Price Vice Manager' FROM DUAL
Then after the MERGE the table contains:
EKLENECEKKOLON
MER.Price Vice Manager.XYZ
fiddle

How to return a variable-langth string from a string

I have the following dataset:
Ident
Script
ID1
Var_xxx_calc + Var_yyy_db + Var_zzz_calc
ID2
Var_xxx_calc + Var_zzz_db
Is there any way to split this up into the following table?
Ident
Script
Var1
Var2
Var3
ID1
Var_xxx_calc + Var_yyy_db + Var_zzz_calc
Var_xxx_calc
Var_yyy_db
Var_zzz_calc
ID2
if Var_xxx_calc + Var_zzz_db > 10 then 'OK' else 'NOK'
Var_xxx_calc
Var_zzz_db
null
Extra difficulty:
the Var_% all have different lengths, I only know they start with 'Var_'
I use Oracle Production version 19.12.0.0.0
Tried to find a solution and ended with a limited one. I use a delimiter that is forcefully implanted into the SCRIPT instead of any possible character that could be infront of or just after your 'Var_something' string. You will see it in code as "endless" Replaces. The idea is to set a delimiter if it is posssible just after the string you are trying to separate.
Here is the code with some sample data generaated by WITH clause:
WITH
tbl AS
(
Select 'ID_1' "IDENT", 'Var_xxxxx_calculus + Var_yyy_dbase + Var_zz_calc' "SCRIPT" From Dual Union All
Select 'ID_2' "IDENT", 'Var_xxxxx_calcul + Var_yyy_dbase' "SCRIPT" From Dual Union All
Select 'ID_3' "IDENT", 'If Var_xxx_calc + Var_zzz_db* 2 > 10 then "OK" else "NOK"' "SCRIPT" From Dual Union All
Select 'ID_4' "IDENT", 'Some other text without Var followed by underscore' "SCRIPT" From Dual Union All
Select 'ID_5' "IDENT", 'And some with "Var_" Var_A, Var_B, Var_C in it' "SCRIPT" From Dual
)
SELECT
IDENT "IDENT",
SCRIPT "SCRIPT",
CASE
WHEN VAR_COUNT > 0 THEN
SubStr( SCRIPT_DELIMITED,
InStr(SCRIPT_DELIMITED, 'Var_', 1, 1),
InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 1), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 1)
)
END "VAR_1",
CASE
WHEN VAR_COUNT > 1 THEN
SubStr( SCRIPT_DELIMITED,
InStr(SCRIPT_DELIMITED, 'Var_', 1, 2),
InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 2), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 2)
)
END "VAR_2",
CASE
WHEN VAR_COUNT > 2 THEN
SubStr( SCRIPT_DELIMITED,
InStr(SCRIPT_DELIMITED, 'Var_', 1, 3),
InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 3), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 3)
)
END "VAR_3",
CASE
WHEN VAR_COUNT > 3 THEN
SubStr( SCRIPT_DELIMITED,
InStr(SCRIPT_DELIMITED, 'Var_', 1, 4),
InStr(SCRIPT_DELIMITED, ';', InStr(SCRIPT_DELIMITED, 'Var_', 1, 4), 1) - InStr(SCRIPT_DELIMITED, 'Var_', 1, 4)
)
END "VAR_4"
FROM
(
SELECT
IDENT "IDENT",
SCRIPT "SCRIPT",
CASE
WHEN InStr(SCRIPT, 'Var_', 1, 4) > 0 THEN 4
WHEN InStr(SCRIPT, 'Var_', 1, 3) > 0 THEN 3
WHEN InStr(SCRIPT, 'Var_', 1, 2) > 0 THEN 2
WHEN InStr(SCRIPT, 'Var_', 1, 1) > 0 THEN 1
ELSE 0
END "VAR_COUNT",
Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(SCRIPT, ' ', ';'), '+', ';'), '>', ';'), '<', ';'), '=', ';'), '"', ';'), '*', ';'), ',', ';') || ';' "SCRIPT_DELIMITED"
FROM
tbl
)
It is limited here with four variables selected for separation and with a condition that there is no other separation character than those treated with Replace functions.
The result with sample data is:
-- IDENT SCRIPT VAR_1 VAR_2 VAR_3 VAR_4
-- ----- --------------------------------------------------------- ---------------------------------------------------------- ---------------------------------------------------------- ---------------------------------------------------------- ----------------------------------------------------------
-- ID_1 Var_xxxxx_calculus + Var_yyy_dbase + Var_zz_calc Var_xxxxx_calculus Var_yyy_dbase Var_zz_calc
-- ID_2 Var_xxxxx_calcul + Var_yyy_dbase Var_xxxxx_calcul Var_yyy_dbase
-- ID_3 If Var_xxx_calc + Var_zzz_db* 2 > 10 then "OK" else "NOK" Var_xxx_calc Var_zzz_db
-- ID_4 Some other text without Var followed by underscore
-- ID_5 And some with "Var_" Var_A, Var_B, Var_C in it Var_ Var_A Var_B Var_C
Regards...
Here's a solution using REGEXP_SUBSTR(). In the WITH clause, the 'tbl' table just sets up sample data from your original post. The select gets the first, second and third occurances of the pattern 'Var_', followed by one or more non-greedy characters, another underscore, another set of one or more non-greedy characters, where followed by a space and a character OR the end of the line. If the Var value could only contain alpha characters it would be better to specify that in order to tighten up the match and not risk including accidental values.
Caveat: It only selects 3 values per your original post.
WITH tbl(ident, script) AS (
SELECT 'ID1', 'Var_xxx_calc + Var_yyy_db + Var_zzz_calc' FROM dual UNION ALL
SELECT 'ID2', 'Var_xxx_calc + Var_zzz_db' FROM dual UNION ALL
SELECT 'ID3', 'Var_xxx_calc + Var_yyy_db + Var_zzz_calc' FROM dual UNION ALL
SELECT 'ID4', 'IF Var_xxx_calc + Var_zzz_db > 10 THEN ''OK'' ELSE ''NOK''' FROM dual
)
SELECT ident,
REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 1, NULL, 1) AS Var1,
REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 2, NULL, 1) AS Var2,
REGEXP_SUBSTR(script, '(Var_.+?_.+?)( .|$)', 1, 3, NULL, 1) AS Var3
FROM tbl;
IDENT VAR1 VAR2 VAR3
----- --------------- --------------- ---------------
ID1 Var_xxx_calc Var_yyy_db Var_zzz_calc
ID2 Var_xxx_calc Var_zzz_db
ID3 Var_xxx_calc Var_yyy_db Var_zzz_calc
ID4 Var_xxx_calc Var_zzz_db
4 rows selected.

How do I get substring after a character when the occurance of the character keeps changing

Example
123\.456.578.910.ABC
123\.456.578.910
Expected result
123\.456.578
123\.456.578
For the both the inputs I should get only the first 3
I tried the regexp and substring and instr but I’m not getting the results
We can use REGEXP_SUBSTR here with a capture group:
SELECT REGEXP_SUBSTR(col, '^(\d+(\.\d+)*)', 1, 1, NULL, 1)
FROM yourTable;
Demo
Traditional, substr + instr combination is another option:
Sample data:
SQL> with test (col) as
2 (select '123\.456.578.910.ABC' from dual union all
3 select '123\.456.578.910' from dual
4 )
Query begins here:
5 select col,
6 substr(col, 1, instr(col, '.', 1, 3) - 1) result
7 from test;
COL RESULT
-------------------- --------------------
123\.456.578.910.ABC 123\.456.578
123\.456.578.910 123\.456.578
SQL>
If you value will always have at least 3 . characters then you can use:
SELECT value,
SUBSTR(value, 1, INSTR(value, '.', 1, 3) - 1) AS expected
FROM table_name;
If it may have fewer and you want the entire string in those cases then:
SELECT value,
CASE INSTR(value, '.', 1, 3)
WHEN 0
THEN value
ELSE SUBSTR(value, 1, INSTR(value, '.', 1, 3) - 1)
END AS expected
FROM table_name;
Which, for your sample data:
CREATE TABLE table_name (value) AS
SELECT '123\.456.578.910.ABC' FROM DUAL UNION ALL
SELECT '123\.456.578.910' FROM DUAL;
Both outputs:
VALUE
EXPECTED
123.456.578.910.ABC
123.456.578
123.456.578.910
123.456.578
db<>fiddle here

REGEXP_SUBSTR SPLIT Function

i want to split this into 2019/GA/0000104
select REGEXP_SUBSTR('2019/0000015,2019/GA/0000104,2cdb376e-2966-4f24-9063-f4c6f31a6f35', '[^,]+')
from dual;
Output = 2019/GA/0000104
can u guys help?
It seems that you want to extract the second substring. If that's so, then you could use
regexp_substr (result), or
substr + inenter code herestr combination (result2)
SQL> with test (col) as
2 (select '2019/0000015,2019/GA/0000104,2cdb376e-2966-4f24-9063-f4c6f31a6f35' from dual)
3 select regexp_substr(col, '[^,]+', 1, 2) result,
4 --
5 substr(col, instr(col, ',', 1, 1) + 1,
6 instr(col, ',', 1, 2) - instr(col, ',', 1, 1) - 1
7 ) result2
8 from test;
RESULT RESULT2
--------------- ---------------
2019/GA/0000104 2019/GA/0000104
SQL>
Try using REGEXP_SUBSTR with a capture group:
SELECT
REGEXP_SUBSTR(input, ',(.*),', 1, 1, NULL, 1)
FROM yourTable;
Demo
This form of the regex returns the second occurrence of a string of characters that are followed by a comma or the end of the line. It returns the correct element if the first one should ever be NULL.
with tbl(str) as (
select '2019/0000015,2019/GA/0000104,2cdb376e-2966-4f24-9063-f4c6f31a6f35' from dual
)
select regexp_substr(str, '(.*?)(,|$)', 1, 2, NULL, 1)
from tbl;