Oracle SQL - Reading delimiter - sql

I'm developing a command in Oracle SQL using a table that has that type of row:
company=1&product=12588&version=1
For my command, I need the product number and version of each row, but separated by columns.
My first question: How can I read only the product number, using something different of REGEXP_SUBSTR
My second question: What is the best way to create a new column to show the version without duplicate the line?
I hope someone can help me.

If data really is that simple, regular expressions make code rather simple. Way simpler than SUBSTR + INSTR option. Why don't you want to use regex? Because it is evil, or ...?
sample data in lines #1 - 4
product: take the 2nd numeric value from the column
version: take the last numeric value from the column
SQL> with test (col) as
2 (select 'company=1&product=12588&version=1' from dual union all
3 select 'company=2&product=52361&version=4' from dual
4 )
5 select col,
6 regexp_substr(col, '\d+', 1, 2) as product,
7 regexp_substr(col, '\d+$') as version
8 from test;
COL PRODUCT VERSION
--------------------------------- ---------- ----------
company=1&product=12588&version=1 12588 1
company=2&product=52361&version=4 52361 4
SQL>
As of
What is the best way to create a new column to show the version without duplicate the line?
I have no idea what that means. "Without duplicate the line"? Which line? Which duplicate?

To answer your first question, you can use sql below by combining only the ** substr ** and ** instr ** functions.
This solution takes advantage of the four and last parameter of the instr function.
select your_column
, substr(your_column
, instr(your_column, '=', 1, 1) + 1
, instr(your_column, '&', 1, 1) - instr(your_column, '=', 1, 1) - 1
) company
, substr(your_column
, instr(your_column, '=', 1, 2) + 1
, instr(your_column, '&', 1, 2) - instr(your_column, '=', 1, 2) - 1
) product
, substr(your_column
, instr(your_column, '=', 1, 3) + 1
) version
from (
select 'company=1&product=12588&version=1' your_column from dual union all
select 'company=2&product=52361&version=4' your_column from dual
) Your_data
;
demo
But, I'm not sure I understood your second question correctly.

Related

how to get the string before first occurrence of a special character [duplicate]

This question already has answers here:
How to Select a substring in Oracle SQL up to a specific character?
(8 answers)
Closed 1 year ago.
i have a column containing hostnames in the format of :
oraclehost.server.region.company.net
How to extract the oraclehost part from the hostname i.e the string before the first ..
Please sugges.Thanks.
SELECT REGEXP_SUBSTR(HOSTNAMES, '[^.]+', 1, 1) FROM MYTABLE;
Alternatively, substr + instr combination which would probably perform better for large data sets:
substr(hostnames, 1, instr(hostnames, '.') - 1)
For example:
SQL> with mytable (hostnames) as
2 (select 'oraclehost.server.region.company.net' from dual)
3 select substr(hostnames, 1, instr(hostnames, '.') - 1) result
4 from mytable;
RESULT
----------
oraclehost
SQL>

shorten the string to the desired values

I have a table with a "Link" attribute. It has the following meaning:
INC102
INC1020
INC10200
I want to get the following result:
INC102
INC1020
INC10200
I need to leave the INC and the numbers after it without .
Tell me which command will help here? Since I understand that "Substr" will not work here.
I am use SQL Developer - Oracle
If you just want to extract "INC" with the following digits, use regexp_substr():
select regexp_substr(link, 'INC[0-9]+')
Here is a db<>fiddle.
Since I understand that "Substr" will not work here.
Says who?
SQL> with test (col) as
2 (select 'INC102' from dual union all
3 select 'INC1020' from dual union all
4 select 'INC10200' from dual
5 )
6 select
7 substr(col,
8 instr(col, '>') + 1,
9 instr(col, '<', instr(col, '>')) - instr(col, '>') - 1
10 ) result
11 from test;
RESULT
------------------------------------------------------------------------------------------------------------------------
INC102
INC1020
INC10200
SQL>
What does it do?
lines #1 - 5: sample data
line #8: starting point of the SUBSTR function is one character after the first > sign
line #9: length (used as the 3rd parameter of the SUBSTR) is position of the first < that follows the first > minus position of the first >
And that's it ... why wouldn't it work?
You could treat [<>] as the word delimiter and take the second word:
with test (col) as
( select 'INC102' from dual union all
select 'INC1020' from dual union all
select 'INC10200' from dual
)
select regexp_substr(col,'[^<>]+', 1, 2)
from test;
REGEXP_SUBSTR(COL,'[^<>]+',1,2)
-------------------------------
INC102
INC1020
INC10200

How to extract the number from a string using Oracle?

I have a string as follows: first, last (123456) the expected result should be 123456. Could someone help me in which direction should I proceed using Oracle?
It will depend on the actual pattern you care about (I assume "first" and "last" aren't literal hard-coded strings), but you will probably want to use regexp_substr.
For example, this matches anything between two brackets (which will work for your example), but you might need more sophisticated criteria if your actual examples have multiple brackets or something.
SELECT regexp_substr(COLUMN_NAME, '\(([^\)]*)\)', 1, 1, 'i', 1)
FROM TABLE_NAME
Your question is ambiguous and needs clarification. Based on your comment it appears you want to select the six digits after the left bracket. You can use the Oracle instr function to find the position of a character in a string, and then feed that into the substr to select your text.
select substr(mycol, instr(mycol, '(') + 1, 6) from mytable
Or if there are a varying number of digits between the brackets:
select substr(mycol, instr(mycol, '(') + 1, instr(mycol, ')') - instr(mycol, '(') - 1) from mytable
Find the last ( and get the sub-string after without the trailing ) and convert that to a number:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE test ( str ) AS
SELECT 'first, last (123456)' FROM DUAL UNION ALL
SELECT 'john, doe (jr) (987654321)' FROM DUAL;
Query 1:
SELECT TO_NUMBER(
TRIM(
TRAILING ')' FROM
SUBSTR(
str,
INSTR( str, '(', -1 ) + 1
)
)
) AS value
FROM test
Results:
| VALUE |
|-----------|
| 123456 |
| 987654321 |

Oracle sql : get only specific part of a substring

I'm struggling with a query in Oracle SQL, wanting to get some timings out of some text stored in an Oracle db.
Table :
kde_test (myString varchar(50))
Table contents (3 records):
'task1 - 6m'
'task2 - 66m'
'task3 - 666m'
I would like to get only the interesting part of the string, being the timings, so I would like to get only '6', '66' & '666' as results.
Searched this forum a bit, and got up with this query eventually, but it seems I do not completely get it, as the results it returns are :
6m
66m
666m
select
CASE
WHEN myString like 'task1%' THEN substr(myString,9,INSTR(myString,'m',1,1)-1)
WHEN myString like 'task2%' THEN substr(myString,9,INSTR(myString,'m',1,1)-1)
WHEN myString like 'task3%' THEN substr(myString,9,INSTR(myString,'m',1,1)-1)
END
from kde_test
where myString like 'task%'
EDIT :
Since some solutions (thanks already for quick response) take into account the specific values (eg. all 3 records ending on '6m'), maybe it best to take into account the values could be :
Table contents (3 records):
'task1 - 6m'
'task2 - 58m'
'task3 - 123m'
you can use this way too
select regexp_replace(SUBSTR('task3 - 666m' ,
INSTR('task3 - 666m', '-',1, 1)+1, length('task3 - 666m')), '[A-Za-z]')
from dual
result :666
Use SUBSTR and INSTR and make it dynamic.
SUBSTR(str,
instr(str, ' - ', 1, 1) +3,
instr(str, 'm', 1, 1) -
instr(str, ' - ', 1, 1) -3
)
For example,
SQL> WITH DATA AS(
2 SELECT 'task1 - 6m' str FROM dual UNION ALL
3 SELECT 'task2 - 66m' str FROM dual UNION ALL
4 SELECT 'task3 - 666m' str FROM dual UNION ALL
5 SELECT 'task4 - 58m' str FROM dual UNION ALL
6 SELECT 'task5 - 123m' str FROM dual
7 )
8 SELECT str,
9 SUBSTR(str, instr(str, ' - ', 1, 1) +3,
10 instr(str, 'm', 1, 1) - instr(str, ' - ', 1, 1) -3) new_st
11 FROM DATA;
STR NEW_STR
------------ ------------
task1 - 6m 6
task2 - 66m 66
task3 - 666m 666
task4 - 58m 58
task5 - 123m 123
SQL>
You can use the regex_substr function. \d+ means one or more digits, and $ anchors the end of the string.
select regexp_substr(str, '\d+m$')
from mytable
Example at SQL Fiddle.
In order to correct your current query, you should change the following string - "INSTR(myString,'m',1,1)-1" to "INSTR(myString,'m',1,1)-9".
However, the other answers provided above seem like a more elegant solution to your problem.
I did feel the need to publish this just to clarify what wasn't working well in current query - in INSTR function returns the position of the m letter, and then used as the length of the string to print. What my fix does is telling the query to print everything from the 9th character until the position of the m letter, which results in the task time required.
I have tried to divide this into two parts
First pick the string after -
regexp_substr ('task1 - 1234m', '[^ _ ]+',1, 3) --results 1234m
Fetch the number part of the string fetched from output of first
regexp_substr(regexp_substr ('task1 - 1234m', '[^ _ ]+',1, 3),'[[:digit:]]*')
--output 1234
So,the final query is
SELECT regexp_substr(regexp_substr (mystring, '[^ _ ]+',1, 3),'[[:digit:]]*')
FROM kde_test;
Use This:-
select substr(replace(myString,'m',''),9) output
from kde_test
where myString like 'task%'

SQL substr function

in my table one column contains data as below
BMS/430301420-XN/0
I need to use substr function in oracle and output to be taken as
430301420-XN
the one I used is as below
substr(buy_id,5),substr(substr(buy_id,5),instr(buy_id,'/',2))
but it is not working please help me
If you know the format of the string and you always want to start on the fifth character and remove the last two, then:
select substr(str, 5, -2)
If you just want the part between the slashes, then use regexp_substr():
select replace(regexp_substr(str, '/.*/'), '/', '')
Easiest way is a Regular Expression, find the string between the slashes but don't include them in the result:
regexp_substr(buy_id, '(?<=/).*(?=/)')
With a combination of SUBSTR and INSTR:
SQL> WITH DATA AS(
2 SELECT 'BMS/430301420-XN/0' str FROM dual UNION ALL
3 SELECT 'BMSABC/430301420-XN/0' str FROM dual UNION ALL
4 SELECT 'BMS/430301420-XN/012345' str FROM dual
5 )
6 SELECT str,
7 SUBSTR(str, instr(str, '/', 1, 1)+1, instr(str, '/', 1, 2)
8 -instr(str, '/', 1, 1)-1) new_str
9 FROM DATA;
STR NEW_STR
----------------------- -----------------------
BMS/430301420-XN/0 430301420-XN
BMSABC/430301420-XN/0 430301420-XN
BMS/430301420-XN/012345 430301420-XN
SQL>
The above uses the logic to find the substring between the first and second occurrence of the /.
This will also Work :D
select Column_Name as OLD , substr(''||to_char(Column_Name)||'',instr
(''||to_char(Column_Name)||'','/',1)+1,(instr(''||to_char(Column_Name)
||'','/',1,2)-instr(''||to_char(Column_Name)||'','/',1,1)-1)) as NEW from Table_Name;
Same Use Of substr and instr
my answer is :
select
substr('BMS/430301420-XN/0',
(instr('BMS/430301420-XN/0','/') +1),
(instr('BMS/430301420-XN/0','/',(instr('BMS/430301420-XN/0','/')+1))-instr('BMS/430301420-XN/0','/')-1 ))
from dual
you can see this sample :
http://www.sqlfiddle.com/#!4/9eecb7/863/0