oracle regex functions to format us phone numbers - sql

I'm trying to format us phone numbers using Oracle regular expression.
I have to use below conditions
if count of digits < 10 then null
if count of digits = 10 then format the phone number as 111-111-1111
if count of digits > 10 and has a plus sign at the front then format the
digits by skipping first digit after plus sign as 111-111-1111
if count of digits > 10 and has no plus sign at the front then format the first 10 digits as 111-111-1111
See examples below for all 4 cases
+(555) --> NULL
1112223333 --> 111-222-3333
+1 (123) 1111111 x1111 --> 123-111-1111
(111)1111111 Ext. 1111 --> 111-111-1111
(111) 111-1111 ext 1111 --> 111-111-1111
2 111-111-1111 --> 211-111-1111
Thank you for your help.

The simplest way to do this (without regular expressions):
Strip out the non-digit characters with translate()
Reduce to ten digits with substr()
Re-format with substr()
So:
with cte as
( select substr (
translate ( phone
, '1234567890' || phone
, '1234567890'
) , 1, 10 ) as clean_phone
from your_table
)
select case
when length(clean_phone) = 10 then
substr(clean_phone, 1, 3)
||'-'||
substr(clean_phone, 4, 4)
||'-'||
substr(clean_phone, 7, 4)
else null end as fmt_phone
from cte
Tip of the hat to #mathguy for the translate() implementation.

I used a nested SQL.
In the innermost step, tried to get rid of digit after plus sign and all non-numeric characters by using regexp_replace and substr,
and then converted to the desired format by using format model as argument of to_char function as below :
select (case when length(str_)<10 then null
else
replace(to_char(substr(str_,1,10),'fm999,999,9999'),',','-')
end)
as str
from
(
select (case when substr(str,1,1)='+' then
regexp_replace(substr(str,3,length(str)),'[^0-9]','')
else
regexp_replace(str,'[^0-9]','')
end) as str_
from tab
);
SQL Fiddle Demo

REGEXP_REPLACE(phone,'^(+?1[.[:space:]-])?(?(\d{3})(\d*).*','\2-\3')

Related

Remove only first character from the field if it is 0

How to write sql query which will show values skipping first character if it is 0 (only the first character). All values are 3 characters long.
Examples:
numbers
123
023
003
102
should display as follows (after executing the query)
numbers
123
23
03
102
I used the following solution, but it removes all 0's, not just the first. How to fix it so that it only removes the first character if it is 0.
SUBSTRING(numbers, PATINDEX('%[^0]%', numbers+'.'), LEN(numbers))
I will be grateful for your help.
You can use CASE expression:
SELECT CASE WHEN LEFT(numbers, 1) = '0' THEN RIGHT(numbers, 2) ELSE numbers END AS FormattedNumbers
why not using simple substr() ?
select case when substr(mycol,1,1)='0' then substr(mycol,2) else mycol end
from my table
you did not mention your DB so i assumed its oracle. This will work in any RDBMS.
You can use charindex and substring methods to do string manipulation :)
select
case when charindex('0', number) = 1
then substring(number, 2, len(number))
else number end
from (
select '123' number
union all
select '023'
union all
select '003'
union all
select '102'
) a

Trim leading 0 for length greater than x in a dataset

Take this table for example
Table 1:
Name. ID
David 00513
George 0523
Carmen 3216
In this table, I want to trim the leading 0 for David only, because his ID is greater than 4 digits. I don't want to trim the leading 0 for George
Whats the best way to do this in SQL?
The simplest way is simply:
select right(id, 4)
If you are concerned about ids longer than 4 character but with non-zero initial characters:
select (case when length(id) > 4
then replace(ltrim(replace(id, '0', ' ')), ' ', '0')
else id
end)
If you're not concerned with initial non-zeros getting chopped, then
select substr(ID,-4);
should work. If there is possibility of having more than 4 digits with a non-zero initial, then use
select printf('%04d', ID);
(Assuming that all characters in ID are digits)

Number check in oracle sql

How to check in 10 digit number whether it contain 999 or 000 in the 4-6th bytes ?
I have a n idea with using INSTR but i don't know how to execute it
This is strange. If the "number" is really a string, then you can use like or substr():
where col like '___999%' or col like '___000%'
or:
where substr(col, 4, 3) in ('999', '000')
or even regular expressions.
Given the nature of your question, you can turn a number into a string and use these methods. However, if you are looking at particular digits, then the "number" should be stored as a string.
If they are actually numbers rather than strings then you could use numeric manipulation:
with t (n) as (
select 1234567890 from dual
union all select 1239997890 from dual
union all select 1230007890 from dual
union all select 1299967890 from dual
union all select 1234000890 from dual
)
select n,
mod(n, 10000000) as stage1,
mod(n, 10000000)/10000 as stage2,
trunc(mod(n, 10000000)/10000) as stage3,
case when trunc(mod(n, 10000000)/10000) in (0, 999) then 'Yes' else 'No' end as matches
from t;
N STAGE1 STAGE2 STAGE3 MATCHES
---------- ---------- ---------- ---------- -------
1234567890 4567890 456.789 456 No
1239997890 9997890 999.789 999 Yes
1230007890 7890 .789 0 Yes
1299967890 9967890 996.789 996 No
1234000890 4000890 400.089 400 No
Stage 1 effectively strips off the first three digits. Stage two almost strips off the last four digits, but leaves fractions, so stage 3 adds trunc() (you could also use floor()) to ignore those fractional parts.
The result of that is the numeric value of the 4-6th digits, and you can then test if that is 0, 999 or something else.
This is really looking at the 4th to 6th most significant digits, which is the same if the number is always 10 digits; if it might actually have different numbers of digits then you'd need to clarify what you want to see.
select
1 from dual where instr(98800054542,000,4,3)in (6) or instr(98800054542,999,4,3)in (6); let me know if this helped.

sql query about string function

ID MOBILE
1 9869600733
2 9869600793
3 9869600799
all id whose mobile number containing 9 three times(using string functions like replace, substr, etc)... ? (without like , % , etc)
You can use LEN and Replace
Where len(MOBILE)-len(replace(MOBILE ,'9',''))>=3
Note : Some DBMS uses LENGTH instead of LEN
Where length(MOBILE)-length(replace(MOBILE ,'9',''))>=3
DEMO
replace(MOBILE ,'9','') will replace all the 9's with empty
string
length(MOBILE) will count the number of characters in Mobile
column
length(replace(MOBILE ,'9','')) will count the number of characters
in Mobile column as replacing 9's with empty string
length(MOBILE)-length(replace(MOBILE ,'9','')) here the
difference will tell the number of missing characters that is our 9, you can use this difference to count the 9
exactly three '9's:
Select * from mytable
Where len(mobile) - len(replace(mobile, '9', '')) = 3
at least three '9's:
Select * from mytable
Where len(mobile) - len(replace(mobile, '9', '')) >= 3

SQL How to extract numbers from a string?

I am working on a query in SQL that should be able to extract numbers on different/random lenght from the beginning of the text string.
Text string: 666 devils number is not 8888.
Text string: 12345 devils number is my PIN, that is 6666.
I want to get in a column
666
12345
Use a combination of Substr & instr
SELECT Substr (textstring, 1,instr(textstring,' ') - 1) AS Output
FROM yourtable
Result:
OUTPUT
666
12345
Use this if you have text at the beginning e.g. aa12345 devils number is my PIN, that is 6666. as it utilises the REGEXP_REPLACE function.
SELECT REGEXP_REPLACE(Substr (textstring, 1,instr(textstring,' ') - 1), '[[:alpha:]]','') AS Output
FROM yourtable
SQL Fiddle: http://sqlfiddle.com/#!4/8edc9/1/0
This version utilizes a regular expression which gives you the first number whether or not it's preceded by text and does not use the ghastly nested instr/substr calls:
SQL> with tbl(data) as (
select '666 devils number is not 8888' from dual
union
select '12345 devils number is my PIN, that is 6666' from dual
union
select 'aa12345 devils number is my PIN, that is 6666' from dual
)
select regexp_substr(data, '^\D*(\d+) ', 1, 1, null, 1) first_nbr
from tbl;
FIRST_NBR
---------------------------------------------
12345
666
12345
SQL>