SUBSTR in sql oracle from right - sql

I have data in table 000_ABC_AXEL. The expectation is that i have to exclude data after the last '_' and get 000_ABC in oracle sql? Any suggestions?
Need sql query to achieve below
for ex:
a_222_4 -- > expected result :a_222
123_xyz_0 -- >expected result :123_xyz

A regex replacement fits your requirement nicely:
SELECT col, REGEXP_REPLACE(col, '_[^_]+$', '') AS col_out
FROM yourTable;

You can do it with simple string functions (which are much faster than regular expressions) by finding the sub-string up to the character before the last underscore:
SELECT SUBSTR(col, 1, INSTR(col, '_', -1) - 1) AS first_parts
FROM table_name;
Which, for the sample data:
CREATE TABLE table_name (col) AS
SELECT 'a_222_4' FROM DUAL UNION ALL
SELECT '123_xyz_0' FROM DUAL;
Outputs:
FIRST_PARTS
a_222
123_xyz
fiddle

Related

Oracle Regex grabbing value from key value pair in a string

Consider the following column row:
col
-------------------------
'{"day":"8","every":"2"}'
I am trying to get 8 from this string using regular expression to figure out the day.
so far I have:
SELECT
regexp_replace(col, '{"day":[^0-9]', '') as "day"
FROM
mytable;
This gives me:
day
---------------
8","every":"2"}
I am having trouble figuring out how to filter out the rest of the string from the first number forward. In my example I just want the number 8 for this row.
When you are lucky enough to use Oracle 12c Release 1 (12.1.0.2) or later, do take a look at JSON_VALUE
WITH t (s)
AS (
SELECT '{"day":"8","every":"2"}'
FROM DUAL
)
SELECT JSON_VALUE(s, '$.day' ) AS day
, JSON_VALUE(s, '$.every') AS every
FROM t;
DAY EVERY
--- -----
8 2
How about this?
SELECT
regexp_replace(col, '{"day":"([0-9]+).*', '\1') as "day"
FROM
mytable;
If you don't have access to JSON_VALUE() then I would recommend the following regex unless you always know the position of the day key in the JSON string:
SELECT REGEXP_REPLACE(col, '^.*"day":"(\d+)".*$', '\1') AS day
FROM mytable;
This will replace the entire string (assuming it matches!) with the contents of the first capturing group (enclosed in parentheses: (\d+)). \d indicates a digit 0-9. If you want to return NULL values as well, you can replace \d+ with \d*. If negative or non-numeric values are possible, then I would recommend the following:
SELECT REGEXP_REPLACE(col, '^.*"day":"([^"]*)".*$', '\1') AS day
FROM mytable;
This will return whatever characters that might be contained in the day key.
FYI, once you have the value, numeric or non-, you can convert it to a number safely by using TO_NUMBER() along with REGEXP_SUBSTR():
SELECT COALESCE( TO_NUMBER( REGEXP_SUBSTR( REGEXP_REPLACE( col, '^.*"day":"[^"]*".*$', '\1' ), '\d+' ) ), 0 ) AS day
FROM mytable;
Hope it helps.

ORACLE:SQL REGEXP_SUBSTR that returns the column value after last backslash(/)

ORACLE:SQL REGEXP_SUBSTR that returns the column value after last backslash(/)
example:
https://test/test/test/test/getTest/1234
expected value: 1234
You don't need regular expressions for this. You can simply using substr and instr which are likely to perform faster:
select
substr(col, instr(col, '/', -1) + 1)
from t;
Demo
If you must use regexp_substr (for some reason) then use:
select regexp_substr(col, '[^/]+$') from t;
Demo
If you need with REGEXP_SUBSTR also, then:
SELECT REGEXP_SUBSTR ('https://test/test/test/test/getTest/1234' , '[^/]+$' ) from dual

using Substr and instr in SQL

I am trying to extract the middle of the string from record. I want to get the only middle of the string.
select instr('WUK00000105376:WUKE03960761:WUKR0093868603',':')
from dual;
I want to get only WUKE03960761 from this string.
I have tried by using sustring and instring to get the output but i am not getting.
SELECT SUBSTR(col,
INSTR(col, ':') + 1,
INSTR(col, ':', 1, 2) - INSTR(col, ':') - 1)
FROM dual
Another option is to use regexp_substring() to get the string between the two colons:
select regexp_substr('WUK00000105376:WUKE03960761:WUKR0093868603',':[A-Z0-9]+:')
from dual;
This however would also return the colons, but you can also tell regexp_substr() to return a specific group from the regex:
select regexp_substr('WUK00000105376:WUKE03960761:WUKR0093868603',':([A-Z0-9]+):',1,1,'i',1)
from dual;
But Tim's solution using substr and instr is most likely going to be a lot faster.

how to split the value in oracle

I have worked with MySQL and new to oracle. In MySQL we have a function SUBSTRING_INDEX(), I want to replace it in oracle, Any help plz
SQL>select SUBSTRING_INDEX('JD;EQ;0001', ';', -1) from dual;
Result:
0001
I want a same result in oracle. Is there any function in oracle that return the same result in oracle?
I have tried but no expected result.
SELECT substr('CLUBORACLE',3,2) RES FROM dual;
SELECT SUBSTR('JD;EQ;0001', INSTR('JD;EQ;0001', ';', -1) + 1) FROM dual
In the query above, INSTR('JD;EQ;0001', ';', -1) would return 6, which is the position of the last semicolon in the expression. You want to take the substring from the position after the last semicolon until the end of the string.
Look here for a good SO question about Oracle's INSTR.
You can also use regex: SELECT REGEXP_SUBSTR('JD;EQ;0001', '[^;]+', 1, your_occurance_number) FROM dual; but SUBSTR+INSTR should be faster.

How to calculate the number of occurrences of a character in a varchar in a single SQL?

Say there is a variable
v_Source := 'stack#over#flo#w';
How to get the number of occurrences of '#' in it in a single SQL query?
select length('stack#over#flo#w') - length(replace('stack#over#flo#w','#',null))
from dual;
From oracle 11 you can use REGEXP_COUNT
select REGEXP_COUNT('stack#over#flo#w', '#') from dual;
SELECT REGEXP_COUNT( 'stack#over#flo#w', '#' )
FROM DUAL