Oracle SQL split column using string functions - sql

In a table(football_team) the values in a column(names) looks like this Andrew Luck , QB . I want to split this column into 3 columns first_name,Last_name,position using PL/SQL functions.
i tried this
select regexp_substr(names,'[^ ,"]+',1,1) as first_name,
regexp_substr(names,'[^ ,"]+',1,2) as last_name,
regexp_substr(names,'[^ ,"]+',1,3) as position from football_team;
doesn't work
Can I make it by using only SUBSTR and INSTR functions.
Please help me. Thanks in advance.

Yes you could use string functions too but IMO regexp is much simpler here. Well as long as you can read regexps, YMMV.
The problem is in regular expressions. Try this instead:
with names(name) as (
select 'Andrew Luck , QB' from dual
union all
select 'John Doe , WB' from dual
)
select
regexp_substr(name, '^([[:alpha:]]+)', 1, 1, '', 1) as firstname
,regexp_substr(name, '^[[:alpha:]]+[[:space:]]+([[:alpha:]]+)', 1, 1, '', 1) as lasttname
,regexp_substr(name, '([[:alpha:]]+)$', 1, 1, '', 1) as position
from names
;
Returns:
FIRSTNAME LASTNAME POSITION
--------- -------- --------
Andrew Luck QB
John Doe WB
The firstname matching regular expressions explained:
^ -- start of the string
( -- start of subexpression group that is referenced by regexp_substr parameter #6 (subexpr)
[ -- start of matching character list
[:alpha:] -- character class expression: alphabet.
] -- end of matching character list
+ -- matches one or more occurrences of the preceding subexpression
) -- end of subexpression group
The explanantion of other two regexps are left as an excercise for the OP.

Related

substr Error -- ORA-01722:invaild number separate string

I am trying to separate first and last name . I have a column called 'Fullname' and it has first and last name and a comma all in one column. I've tried the below but I get an error " its not a valid number". When I remove the comma it works, so I am not sure how to incorporate a comma in the formula so it can work.
,substr(Fullname,1,',') as Lastname
,substr(Fullname,',',' ') as Firstname
Column
Fullname
Brown,John N
Green,Julie T
Desired results
Lastname FirstName
Brown John
Green Julie
You can use regexp_substr():
select regexp_substr(name, '[^,]+', 1, 1) as lastname,
regexp_substr(name, '[^, ]+', 1, 2) as firstname
The second argument to SUBSTR() is the position of the substring, the third argument is the length of the substring. It will not automatically search for a delimiter if you use strings there instead of numbers. You can use LOCATE() to find the positions that you want.
SUBSTR(Fullname, 1, LOCATE(Fullname, ',')-1) AS Lastname,
SUBSTR(Fullname, LOCATE(Fullname, ',')+1) AS Firstname
Can be performed in Classical way by using instr inside substr function as the following case :
select substr(fullname,1,instr(fullname,',')-1) Firstname,
substr(fullname,instr(fullname,',')+1,length(fullname)) Lastname
from tab;
SQL Fiddle Demo

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 |

Query to remove all non-digit but only keep last period/dot

Struggle to design a regular expression to filter field value from varchar2 to number, so that it can remove all non-digit and only left the last period in the string, so that
"about 1,000.00" return 1000.00 or 1000
"3,000,000.000" return 300000.000 or 3000000
"3.000.000.000" return return 3000000.000 or 3000000
"a^*3^%*(C4.5d*9" return 34.59
Any method just change the string into accurate convertible string that can be converted by to_number()
I use
SELECT REGEXP_REPLACE(field_value, '[^0-9\.]+', '') from dual;
but can't resolve the 3rd case....
Because the regex in oracle are somewhat limited I don't think it's possible only using regexp_replace. You could do a workaround like this:
SELECT
CASE
WHEN last_dot < 2 THEN digits_and_dots
ELSE REPLACE(SUBSTR(digits_and_dots, 1, last_dot - 1), '.') ||
SUBSTR(digits_and_dots, last_dot)
END
FROM (
SELECT
INSTR(digits_and_dots, '.', -1) last_dot,
digits_and_dots
FROM (
SELECT
REGEXP_REPLACE(field_value, '[^0-9\.]+', '') digits_and_dots
FROM DUAL
) t
) o
Here's a way to do it, assuming there is one decimal character. The value you are working with is a string so I think of the decimal that we want to keep as a separator of the string and split it into 2 parts based on that. The first part is all characters leading up to but not including the last decimal, the second part is the last decimal and all characters after it. Then apply the replace, getting rid of everything that is not a number from the first part, and everything that is not a number or a decimal from the second part, then concatenate them together. Needs more testing with varied inputs but you get the idea. All these regular expressions are kind of expensive though so I doubt this will be the fastest solution.
with tbl(str) as (
select 'about 1,000.00' from dual union
select '3,000,000.000' from dual union
select '3.000.000.000' from dual union
select 'a^*3^%*(C4.5d*9' from dual
)
select str original,
regexp_replace(regexp_substr(str, '^(.*)\.', 1, 1, NULL, 1), '[^0-9]+', '') ||
regexp_replace(regexp_substr(str, '.*(\..*)$', 1, 1, NULL, 1), '[^0-9\.]+', '') Converted
from tbl;
SQL> /
ORIGINAL CONVERTED
--------------- ---------------
3,000,000.000 3000000.000
3.000.000.000 3000000.000
a^*3^%*(C4.5d*9 34.59
about 1,000.00 1000.00
SQL>
Shortest way is as follows:
select regexp_substr('a^*3^%*(C4.5d*9s','\d+\.\d+') from dual;
or
select regexp_replace('a^*3^%*(C4.5d*9s', '[^0.0-9]', '') from dual;

Using REGEXP_SUBSTR with Strings Qualifier

Getting Examples from similar Stack Overflow threads,
Remove all characters after a specific character in PL/SQL
and
How to Select a substring in Oracle SQL up to a specific character?
I would want to retrieve only the first characters before the occurrence of a string.
Example:
STRING_EXAMPLE
TREE_OF_APPLES
The Resulting Data set should only show only STRING_EXAM and TREE_OF_AP because PLE is my delimiter
Whenever i use the below REGEXP_SUBSTR, It gets only STRING_ because REGEXP_SUBSTR treats PLE as separate expressions (P, L and E), not as a single expression (PLE).
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^PLE]+',1,1) from dual;
How can i do this without using numerous INSTRs and SUBSTRs?
Thank you.
The problem with your query is that if you use [^PLE] it would match any characters other than P or L or E. You are looking for an occurence of PLE consecutively. So, use
select REGEXP_SUBSTR(colname,'(.+)PLE',1,1,null,1)
from tablename
This returns the substring up to the last occurrence of PLE in the string.
If the string contains multiple instances of PLE and only the substring up to the first occurrence needs to be extracted, use
select REGEXP_SUBSTR(colname,'(.+?)PLE',1,1,null,1)
from tablename
Why use regular expressions for this?
select substr(colname, 1, instr(colname, 'PLE')-1) from...
would be more efficient.
with
inputs( colname ) as (
select 'FIRST_EXAMPLE' from dual union all
select 'IMPLEMENTATION' from dual union all
select 'PARIS' from dual union all
select 'PLEONASM' from dual
)
select colname, substr(colname, 1, instr(colname, 'PLE')-1) as result
from inputs
;
COLNAME RESULT
-------------- ----------
FIRST_EXAMPLE FIRST_EXAM
IMPLEMENTATION IM
PARIS
PLEONASM

REGEXP_SUBSTR oracle 11g

All,
I have a input data coming in the following format,
"CUStid":["201","217"],"HireDate":"2016-06-24","EndDate":"2016-08-23"
(or)
"CUStid":["301",""],"HireDate":"2016-06-24","EndDate":"2016-08-23"
I need to output just the customer id from the input data, and when I run the following it is returning null
(REGEXP_SUBSTR (inputdata,
'"CUStid":"([^"]*)"',
1,
1,
NULL,
1))
expected output is:
CUStid1 Custid2
201 217
301
can someone please tell me how can I do this in oracle 11g
Thanks
Use
REGEXP_SUBSTR (inputdata,'"CUStid":"\[(.+)\]"',1,1,null,1)
[ and ] should be escaped with \.
to get "301","" ,"201","217"
Use string manipulation to get the multiple values as separate columns.
If there can be a maximum of 2 values separated by a , use
select
substr(replace(val,'"',''), 1, instr(replace(val,'"',''),',')-1) custid1
,substr(replace(val,'"',''), instr(replace(val,'"',''),',')+1) custid2
from (select REGEXP_SUBSTR (inputdata,'"CUStid":"\[(.+)\]"',1,1,null,1) val
from tablename)
The quick answer is that in your search pattern you are missing a [.
It should be:
'"CUStid":["([^"]*)"' (notice the [ after the colon : )
... and actually (TESTING HELPS!) the [ is a metacharacter in regular expressions, so it must be escaped:
'"CUStid":\["([^"]*)"'
The longer answer is that you need to be able to pick up the second customer id as well, but perhaps you already know how to do that. Good luck!
Edited
Here is the full query:
with inputs (inputdata) as (
select '"CUStid":["201","217"],"HireDate":"2016-06-24","EndDate":"2016-08-23"' from dual
union all
select '"CUStid":["301",""],"HireDate":"2016-06-24","EndDate":"2016-08-23"' from dual
)
select regexp_substr(inputdata, '"CUStid":\["([^"]*)"', 1, 1, null, 1) as custid1,
regexp_substr(inputdata, '"CUStid":\["[^"]*","([^"]*)"', 1, 1, null, 1) as custid2
from inputs;
Result:
CUSTID1 CUSTID2
---------- ----------
201 217
301
2 rows selected.