How to display all numbers only in oracle sql? - sql

How to display all numeric only in oracle sql?
Example:
12345
abcdef
6789
123abc
abc1234
987
Result:
12345
6789
987
Tried this syntax but it doesn’t work:
WHERE ID_No like '%[0-9]%'

One option would be using reverse logic through REGEXP_LIKE() function with '[^0-9]' pattern
SELECT *
FROM t
WHERE NOT REGEXP_LIKE(ID_No, '[^0-9]')
or
with [:digit:] posix as [^[:digit:]] pattern
SELECT *
FROM t
WHERE NOT REGEXP_LIKE(ID_No, '[^[:digit:]]')
Demo

The fastest solution uses standard (non-regular-expression) functions.
select *
from t
where translate(id_no, '~0123456789', '~') is null
;
Note the use of an additional character (I used ~ but you could use any other non-digit character) - this is needed due to Oracle's bizarre specification of TRANSLATE when the third argument is null.
translate will replace every digit with "nothing" (meaning, it will remove them all), while replacing tilde with itself and leaving all other characters untouched. So, the return value is null only if all the characters were digits.
Equivalent solution:
...
where ltrim(id_no, '0123456789') is null

Use REGEXP_LIKE() function:
select * from tablename
where REGEXP_LIKE(ID_No, '^[0-9]+$')

Yet another option, if you are on oracle 12.2 or higher, is to use TO_NUMBER with conversion error clause as follows:
SELECT *
FROM YOUR_TABLE
WHERE TO_NUMBER(ID_NO DEFAULT -1 ON CONVERSION ERROR) <> - 1
OR ID_NO = '-1'
Cheers!!

Related

How to extract only numerics from string in PostgreSQL 8.0.2 Amazon Redshift

I only want the numeric part of this string column:
identity
student:1234
student:56
student:789
id:driver_license-111-AZ
id:learner_permit-222-NY
So that the output should be:
wanted
1234
56
789
111
222
I am using PostgreSQL 8.0.2 (Amazon Redshift) and I think SELECT REGEXP_SUBSTR(identity,'[0-9]') FROM table should work. But it does not. I tried multiple variations of optional arguments in the REGEXP_SUBSTR but I can't get it to work. Would someone please help me? With this function or otherwise.
Well REGEXP_SUBSTR() should work assuming you use the correct regex pattern:
SELECT REGEXP_SUBSTR(identity, '[0-9]+') -- [0-9]+ means one or MORE digits
FROM yourTable;
You might also be able to phrase this using a regex replacement:
SELECT REGEXP_REPLACE(identity, '[^0-9]+', '') -- strip non digit characters
FROM yourTable;

ORACLE REGEXP limitation?

I'm testing oracle REGEXP_SUBSTR function and regexp that works in Python or Web testing tools like https://regex101.com/ doesn't work with Oracle.
Example:
((?:NF\s{0,1}EN){0,1}[\s]{0,1}ISO[\s]{0,1}[\d]{3,6}(?:[\:]{0,1}\d{1,4}){0,1}[\-]{0,1}\d{0,1})
STRING: VAS H M1582/950-80 ABCDFEF - ISO4014
MATCH: ISO4014, but oracle regexp_like doesn't match:
NOT MATCH:
SELECT REGEXP_SUBSTR (
'VAS H M1582/950-80 ABCDFEF - ISO4014',
'((?:NF\s{0,1}EN){0,1}[\s]{0,1}ISO[\s]{0,1}[\d]{3,6}(?:[\:]{0,1}\d{1,4}){0,1}[\-]{0,1}\d{0,1})')
FROM DUAL;
Any idea?
You can use
(NF\s?EN)?\s?ISO\s?\d{3,6}(:?\d{1,4})?-?\d?
See its demo at regex101.com.
Note:
Oracle regex does not "like" [\s], i.e. shorthand character classes inside brackets, you should not use them like that
{0,1} is equal to ? (one or zero occurrences)
(?:...), non-capturing groups, are not supported, you should replace them with capturing groups. (Note that (:? is not a non-capturing group, it is just an optional colon at the start of the second capturing group in the pattern).
You can use my XT_REGEXP for PCRE compatible regular expressions: https://github.com/xtender/XT_REGEXP
select *
from
table(xt_regexp.get_matches(
'VAS H M1582/950-80 ABCDFEF - ISO4014',
'((?:NF\s{0,1}EN){0,1}[\s]{0,1}ISO[\s]{0,1}[\d]{3,6}(?:[\:]{0,1}\d{1,4}){0,1}[\-]{0,1}\d{0,1})'
));
Results:
COLUMN_VALUE
------------------------------
ISO4014
1 row selected.

Regular Expression in oracle 11g how to retrieve data from a column

I have the following data stored in the database column xyz:
a=222223333;b=433333657675457;c=77777;
a=52424252424242;d=5353535353;b=7373737373;
There is no requirement that b value should always be there but if b value is present I have to retrieve the value following b=.
I want to retrieve the value of b using regular expressions in Oracle and I am unable to do it.
Can anyone please help me find a solution for this?
I suggest using Oracle built-in function REGEXP_SUBSTR which returns a substring using regular expressions. According to the example you posted, the following should work.
SELECT REGEXP_SUBSTR(xyz, 'b=\d+;') FROM your_table
You can use regexp_substr:
select substr(regexp_substr(';' || xyz, ';b=\d+'), 4) from your_table;
Concatenation with ; is to distinguish between key-value pair with key say 'ab' and 'b'.
Use a Subexpression to Select a Substring of Your REGEXP_SUBSTR Matching Pattern
My match pattern, 'b=(\d+);', includes the parenthesis which mark this subexpression which is the last parameter of REGEXP_SUBSTR.
If you look at the 12c documentation, you will see that the third example uses a subexpression.
The escaped d just is a regular expression shorthand to indicate that we are looking for digits and the plus symbol is a quantifier indicating 1 or more digits.
SCOTT#db>WITH smple AS (
2 SELECT
3 'a=52424252424242;d=5353535353;b=7373737373;' dta
4 FROM
5 dual
6 ) SELECT
7 dta,
8 regexp_substr(a.dta,'b=(\d+);',1,1,NULL,1) subexp
9 FROM
10 smple a;
DTA subexp
---------------------------------------------------------
a=52424252424242;d=5353535353;b=7373737373; 7373737373
above solution is working in all the cases even if b contains alphanumeric

using oracle sql substr to get last digits

I have a result of a query and am supposed to get the final digits of one column say 'term'
The value of column term can be like:
'term' 'number' (output)
---------------------------
xyz012 12
xyz112 112
xyz1 1
xyz02 2
xyz002 2
xyz88 88
Note: Not limited to above scenario's but requirement being last 3 or less characters can be digit
Function I used: to_number(substr(term.name,-3))
(Initially I assumed the requirement as last 3 characters are always digit, But I was wrong)
I am using to_number because if last 3 digits are '012' then number should be '12'
But as one can see in some specific cases like 'xyz88', 'xyz1') would give a
ORA-01722: invalid number
How can I achieve this using substr or regexp_substr ?
Did not explore regexp_substr much.
Using REGEXP_SUBSTR,
select column_name, to_number(regexp_substr(column_name,'\d+$'))
from table_name;
\d matches digits. Along with +, it becomes a group with one or more digits.
$ matches end of line.
Putting it together, this regex extracts a group of digits at the end of a string.
More details here.
Demo here.
Oracle has the function regexp_instr() which does what you want:
select term, cast(substr(term, 1-regexp_instr(reverse(term),'[^0-9]')) as int) as number
select SUBSTRING(acc_no,len(acc_no)-1,len(acc_no)) from table_name;

How to Select a substring in Oracle SQL up to a specific character?

Say I have a table column that has results like:
ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore
I would like to be able to write a query that selects this column from said table, but only returns the substring up to the Underscore (_) character. For example:
ABC
DEFGH
IJKLMNOP
The SUBSTRING function doesn't seem to be up to the task because it is position-based and the position of the underscore varies.
I thought about the TRIM function (the RTRIM function specifically):
SELECT RTRIM('listofchars' FROM somecolumn)
FROM sometable
But I'm not sure how I'd get this to work since it only seems to remove a certain list/set of characters and I'm really only after the characters leading up to the Underscore character.
Using a combination of SUBSTR, INSTR, and NVL (for strings without an underscore) will return what you want:
SELECT NVL(SUBSTR('ABC_blah', 0, INSTR('ABC_blah', '_')-1), 'ABC_blah') AS output
FROM DUAL
Result:
output
------
ABC
Use:
SELECT NVL(SUBSTR(t.column, 0, INSTR(t.column, '_')-1), t.column) AS output
FROM YOUR_TABLE t
Reference:
SUBSTR
INSTR
Addendum
If using Oracle10g+, you can use regex via REGEXP_SUBSTR.
This can be done using REGEXP_SUBSTR easily.
Please use
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)
where STRING_EXAMPLE is your string.
Try:
SELECT
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)
from dual
It will solve your problem.
You need to get the position of the first underscore (using INSTR) and then get the part of the string from 1st charecter to (pos-1) using substr.
1 select 'ABC_blahblahblah' test_string,
2 instr('ABC_blahblahblah','_',1,1) position_underscore,
3 substr('ABC_blahblahblah',1,instr('ABC_blahblahblah','_',1,1)-1) result
4* from dual
SQL> /
TEST_STRING POSITION_UNDERSCORE RES
---------------- ------------------ ---
ABC_blahblahblah 4 ABC
Instr documentation
Susbtr Documentation
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) from dual
is the right answer, as posted by user1717270
If you use INSTR, it will give you the position for a string that assumes it contains "_" in it. What if it doesn't? Well the answer will be 0. Therefore, when you want to print the string, it will print a NULL.
Example: If you want to remove the domain from a "host.domain". In some cases you will only have the short name, i.e. "host". Most likely you would like to print "host". Well, with INSTR it will give you a NULL because it did not find any ".", i.e. it will print from 0 to 0. With REGEXP_SUBSTR you will get the right answer in all cases:
SELECT REGEXP_SUBSTR('HOST.DOMAIN','[^.]+',1,1) from dual;
HOST
and
SELECT REGEXP_SUBSTR('HOST','[^.]+',1,1) from dual;
HOST
Another possibility would be the use of REGEXP_SUBSTR.
In case if String position is not fixed then by below Select statement we can get the expected output.
Table Structure
ID VARCHAR2(100 BYTE)
CLIENT VARCHAR2(4000 BYTE)
Data-
ID CLIENT
1001 {"clientId":"con-bjp","clientName":"ABC","providerId":"SBS"}
1002
--
{"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"}
Requirement - Search ClientId string in CLIENT column and return the corresponding value. Like From "clientId":"con-bjp" --> con-bjp(Expected output)
select CLIENT,substr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),1,instr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),'"',1 )-1) cut_str from TEST_SC;
--
CLIENT cut_str
----------------------------------------------------------- ----------
{"clientId":"con-bjp","clientName":"ABC","providerId":"SBS"} con-bjp
{"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"} Test-Cust
Remember this if all your Strings in the column do not have an underscore
(...or else if null value will be the output):
SELECT COALESCE
(SUBSTR("STRING_COLUMN" , 0, INSTR("STRING_COLUMN", '_')-1),
"STRING_COLUMN")
AS OUTPUT FROM DUAL
To find any sub-string from large string:
string_value:=('This is String,Please search string 'Ple');
Then to find the string 'Ple' from String_value we can do as:
select substr(string_value,instr(string_value,'Ple'),length('Ple')) from dual;
You will find result: Ple