How to get specific value from specific position by substr-instr - sql

I have some filename like 'abc-type-bank-20200112-1578796204118.csv'
i want to get the value 'bank' from above which is 3rd value if I cut the string by '-'.
If my filename is like abc-type-XYZ-20200112-1578796204118.csv, I should get 'XYZ' from 3rd position.
I was trying to get by below code, but it giving wrong value.
select substr(v_FILE_NAME,1,instr(v_FILE_NAME, '-') + 3) as name from (
select 'abc-type-bank-20200112-1578796204118.csv' as v_FILE_NAME from dual);

To use SUBSTR and INSTR to extract your desired substring you'd do something like
WITH cteData AS (SELECT 'abc-type-bank-20200112-1578796204118.csv' AS FILENAME FROM DUAL),
ctePos AS (SELECT FILENAME,
INSTR(FILENAME, '-', 1, 2) AS DASH_2_POS,
INSTR(FILENAME, '-', 1, 3) AS DASH_3_POS
FROM cteData)
SELECT SUBSTR(FILENAME, DASH_2_POS + 1, DASH_3_POS - DASH_2_POS - 1) AS SUBSTR_3
FROM ctePos
The above will extract the substring 'bank' from the sample data.
db<>fiddle here

The use of dual suggests Oracle. In that database you can use regexp_substr():
select regexp_substr(filename, '[^-]+', 1, 3)
from (select 'abc-type-XYZ-20200112-1578796204118.csv' as filename from dual) x;

Related

Regex values after special character with empty values

I am struggle with regex to split spring into columns in Oracle database.
select (REGEXP_SUBSTR(replace('1:::9999', ' ',''), '[^: ]+', 1, 4)) from dual;
I need to obtain 4th value from that string as a column value, sometimes values at position 2,3 are empty and my query doesn't work. I am trying to figure out what regex will work
You can use
select (REGEXP_SUBSTR(replace('1:::9999', ' ',''), '([^: ]*)(:|$)', 1, 4, 'i', 1)) from dual;
Here, the ([^: ]*)(:|$) matches
([^: ]*) - Group 1: any zero or more chars other than : and space
(:|$) - Group 2, either : or end of string.
You do not need a (slower) regex for this task, use simple substr/instr functions:
with input_(val) as (
select '1:::9999' from dual
union all
select '1:2::' from dual
union all
select '1:2::3:5' from dual
)
, replaced as (
select input_.*, replace(val, ' ', '') as val_replaced
from input_
)
select
val,
substr(
val_replaced,
/*Locate the first occurrence of a colon and get a substring ...*/
instr(val_replaced, ':', 1, 3) + 1,
/*.. until the end, if the next colon is absent, or until the next colon*/
nvl(nullif(instr(val_replaced, ':', 1, 4), 0), length(val_replaced) + 1) - instr(val_replaced, ':', 1, 3) - 1
) as col
from replaced
VAL
COL
1:::9999
9999
1:2::
null
1:2::3:5
3
fiddle with performance difference.

selected splitted value in oracle

I have two columns A, B in oracle where A value has values like that xx-target-xx
xx any data but target is exists
A
--------
xx-target-xx
xx-target
i neet to return only 'target' from text
i tired this
select TRIM(substr(A, 0, instr(A, '-') - 1)) from mytable
but the result returns xx not target
Use REGEXP_SUBSTR. You want the second string of any characters except the minus sign:
select a, regexp_substr(a, '[^-]+', 1, 2) from mytable;
Using INSTR and SUBSTR instead is a tad more complicated, but possible of course:
select a, substr(a,
instr(a, '-') + 1,
instr(a || '-', '-', 1, 2) - instr(a, '-') - 1
) as value
from mytable;
Demo: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=e75b878bbd6300e9207cd698bb3029ec

In code_subject there are values in the following formats string1#string2#integer#string3. How to extract integer?

In the table code_subject there is a row with a following format string1#string2#integer#string3. How to extract a number (integer) from it?
IS IT LIKE THAT?:
SELECT REGEXP_SUBSTR('integer') "REGEXPR_SUBSTR" FROM code_subject
One way could be using regexp_replace:
select regexp_replace('stringA#stringB#1234#stringC', '[^0-9]', '')
from dual;
Another possibility is:
select substr('string1#string2#1234#string3', instr('string1#string2#1234#string3', '#', 1, 2) + 1,
instr('string1#string2#1234#string3', '#', 1, 3) - instr('string1#string2#1234#string3', '#', 1, 2) - 1)
from dual;

Substring from underscore and onwards in Oracle

I have a string with under score and some characters. I need to apply substring and get values to the left excluding underscore. So I applied below formula and its working correctly for those strings which have underscore (_). But for strings without (_) it is bringing NULL. Any suggestions how this can be handled in the substring itself.
Ex: ABC_BASL ---> Works correctly; ABC ---> gives null
My formula as below -
select SUBSTR('ABC_BAS',1,INSTR('ABC_BAS','_')-1) from dual;
ABC
select SUBSTR('ABC',1,INSTR('ABC','_')-1) from dual;
(NULL)
You could use a CASE expression to first check for an underscore:
WITH yourTable AS (
SELECT 'ABC_BAS' AS col FROM dual UNION ALL
SELECT 'ABC' FROM dual
)
SELECT
CASE WHEN col LIKE '%\_%' ESCAPE '\'
THEN SUBSTR(col, 1, INSTR(col, '_') - 1)
ELSE col END AS col_out
FROM yourTable;
Use regular expression matching:
SELECT REGEXP_SUBSTR('ABC_BAS', '(.*)([_]|$)?', 1, 1, NULL, 1) FROM DUAL;
returns 'ABC', and
SELECT REGEXP_SUBSTR('ABC', '(.*)([_]|$)?', 1, 1, NULL, 1) FROM DUAL;
also returns 'ABC'.
db<>fiddle here
EDIT
The above gives correct results, but I missed the easiest possible regular expression to do the job:
SELECT REGEXP_SUBSTR('ABC_BAS', '[^_]*') FROM DUAL;
returns 'ABC', as does
SELECT REGEXP_SUBSTR('ABC', '[^_]*') FROM DUAL;
db<>fiddle here
Yet another approach is to use the DECODE in the length parameter of the substr as follows:
substr(str,
1,
decode(instr(str,'_'), 0, lenght(str), instr(str,'_') - 1)
)
You seem to want everything up to the first '_'. If so, one method usesregexp_replace():
select regexp_replace(str, '(^[^_]+)_.*$', '\1')
from (select 'ABC' as str from dual union all
select 'ABC_BAS' from dual
) s
A simpler method is:
select regexp_substr(str, '^[^_]+')
from (select 'ABC' as str from dual union all
select 'ABC_BAS' from dual
) s
Here is a db<>fiddle.
I'd use
regexp_replace(text,'_.*')
or if performance was a concern,
substr(text, 1, instr(text||'_', '_') -1)
For example,
with demo(text) as
( select column_value
from table(sys.dbms_debug_vc2coll('ABC', 'ABC_DEF', 'ABC_DEF_GHI')) )
select text
, regexp_replace(text,'_.*')
, substr(text, 1, instr(text||'_', '_') -1)
from demo;
TEXT REGEXP_REPLACE(TEXT,'_.*') SUBSTR(TEXT,1,INSTR(TEXT||'_','_')-1)
------------ --------------------------- -------------------------------------
ABC ABC ABC
ABC_DEF ABC ABC
ABC_DEF_GHI ABC ABC
Ok i think i got it. Add nvl to the substring and insert the condition as below -
select nvl(substr('ABC',1,instr('F4001Z','_')-1),'ABC') from dual;

How to fetch 4 characters from a string in oracle?

By using following query i am able to fetch a particular string.Now this output string contains alphanumeric characters.e.g.abcd123,pqrs542356.
Now i want to fetch only first 4 characters of this string which will be always alpha bates.
Query::
(SELECT SUBSTR(in_msg, INSTR( in_msg,'?', 1, 10 )+ 1, INSTR(in_msg,'?', 1, 11 ) - INSTR( in_msg,'?', 1, 10 )- 1)
FROM emp_message
WHERE emp_no IN (SELECT emp_no
FROM main_table
WHERE name like '%abcd%')
This query returns output as e.g.abcd1234,pqrs145423.
Again i want to fetch only first 4 characters from this query output.
Can somebody help me in this.
You can use substr (like you already do):
SUBSTR(value, 1, 4)
Here it is:
SUBSTR(field, 0, 4)
select substr(x, 1, 4) from
( select x from ..... )