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)
Related
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
This question already has answers here:
Pad a string with leading zeros so it's 3 characters long in SQL Server 2008
(18 answers)
Closed 10 months ago.
I have to add a leading 0 in a column called houses, where it is a unique list of 3 digits, but I wanted have to add a leading 0 to it --> so 4 digits instead of 3.
Can someone help me with this query as the code is incompatible in the '|' operator.
The code is as follows:
select houses from house_numbers
order by houses;
select houses,
case
when len(houses)=3 then '0' | houses
when len(houses)=4 then '' | houses
end as houses
from house_numbers
The string concatenation operator in SQL Server is +, not ||, so you should use:
CASE
WHEN LEN(houses) = 3 THEN '0' + houses
WHEN LEN(houses) = 4 THEN '' + houses
END AS houses
However, a better way to do this would be to just left pad with zero to a length of 4:
RIGHT('0000' + ISNULL(houses, ''), 4) AS houses
You are looking for the CONCAT function here, assuming you are dealing with varchars
when len(houses)=3 then CONCAT('0' , houses)
You could simplify like so
select houses from house_numbers
order by houses;
select houses,
case
when len(houses)=3 then CONCAT('0' , houses)
else houses
end as houses
from house_numbers
Always add the Zero and then strip of the right 4 chars, I believe this might be less resource intensive than doing a case
SELECT RIGHT('0'+CONVERT(VARCHAR(10),345),4) AS Three_Digit_Example,
RIGHT('0'+CONVERT(VARCHAR(10),1345),4) AS Four_Digit_Example
I'm trying to link two tables, one has an 'EntityRef' that's made of four alpha characters and a sequential number...
EntityRef
=========
SWIT1
LIVE32
KIRB48
MEHM38
BRAD192
The table that I'm trying to link to stores the reference in a 15 character field where the 4 alphas are at the start and the numbers are at the end but with zeros in between to make up the 15 characters...
EntityRef
=========
SWIT00000000001
LIVE00000000032
So, to get theses to link, my options are to either remove the zeros on one field or add the zeros on the other.
I've gone for the later as it seems to be a simpler approach and eliminates the risk of getting into problems if the numeric element contains a zero.
So, the alpha is always 4 characters at the beginning and the number is the remainder and 15 minus the LEN() of the EntityRef is the number of zeros that I need to insert...
left(entityref,4) as 'Alpha',
right(entityref,len(EntityRef)-4) as 'Numeric',
15-len(EntityRef) as 'No.of Zeros'
Alpha Numeric No.of Zeros
===== ======= ===========
SWIT 1 10
LIVE 32 9
KIRB 48 9
MEHM 38 9
MALL 36 9
So, I need to concatenate the three elements but I don't know how to create the string of zeros to the specified length...how do I do that??
Concat(Alpha, '0'*[No. of Zeros], Numeric)
What is the correct way to repeat a character a specified number of times?
You can use string manipulation. In this case:
LEFT() to get the alpha portion.
REPLICATE() to get the zeros.
STUFF() to get the number.
The query:
select left(val, 4) + replicate('0', 15 - len(val)) + stuff(val, 1, 4, '')
from (values ('SWIT1'), ('ABC12345')) v(val)
You may try left padding with zeroes:
SELECT
LEFT(EntityRef, 4) +
RIGHT('00000000000' + SUBSTRING(ISNULL(EntityRef,''), 5, 30), 11) AS EntityRef
FROM yourTable;
Demo
With casting to integer the numeric part:
select *
from t1 inner join t2
on concat(left(t2.EntityRef, 4), cast(right(t2.EntityRef, 11) as bigint)) = t1.EntityRef
See the demo.
I found the answer as soon as I posted the question (sometimes it helps you think it through!).
(left(entityref,4) + replicate('0',15-len(EntityRef)) +
right(entityref,len(EntityRef)-4)),
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')
oI have a teradata table with about 10 million records in it, that stores a numeric id field as a varchar. i need to transfer the values in this field to a bigint column in another table, but i can't simply say cast(id_field as bigint) because i get an invalid character error. looking through the values, i find that there could be a character at any position in the string, so let's say the string is varchar(18) i could filter out invalid rows like so :
where substr(id_field,1,1) not in (/*big,ugly array of non-numeric chars*/)
and substr(id_field,2,1) not in (/*big,ugly array of non-numeric chars*/)
etc, etc...
then the cast would work, but this is not feasible in the long run. it's slow and if the string has 18 possible characters, it makes the query unreadable. how can i filter out rows that have a value in this field that will not cast as a bigint without checking each character individually for an array of non-numeric characters?
example values would be
123abc464
a2.3v65
a_356087
........
000000000
BOB KNIGHT
1235468099
the values follow no specific patterns, I simply need to filter out the ones that contain ANY non-numeric data.
123456789 is okay but 123.abc_c3865 is not...
Starting with TD14 Teradata added some functions, now there are multiple ways, e.g.:
WHERE RTRIM(col, '0123456789') = ''
But the easiest way is TO_NUMBER, which returns NULL for bad data:
TO_NUMBER(col)
The best that I've ever managed is this:
where char2hexint(upper(id_field)) = char2hexint(lower(id_field))
Since upper case characters give a different hex value to lower case ones, this will ensure that you have no alphabetical characters, but will still leave you with underscores, colons and so forth. If this doesn't meet your requirements, you may need to write an UDF.
could we also try to divide the values in the field by some integer "if divided then must be a number and if not and throws some error,then must have some character...." guess this would be lot fast as has just mathematics involved...
I've faced the same issue to try to exclude alpha characters from street address house numbers. The following will work if you don't mind concatanating all the numeric numbers together......
It checks if the upper of a string equals the lower of the string, if so it's a number, if not it becomes null.
select cast(case when upper(substring('12E'from 1 for 1)) = lower(substring('12E'from 1 for 1)) then substring('12E'from 1 for 1) else null end ||
case when upper(substring('12E'from 2 for 1)) = lower(substring('12E'from 2 for 1)) then substring('12E'from 2 for 1) else null end ||
case when upper(substring('12E'from 3 for 1)) = lower(substring('12E'from 3 for 1)) then substring('12E'from 3 for 1) else null end ||
case when upper(substring('12E'from 4 for 1)) = lower(substring('12E'from 4 for 1)) then substring('12E'from 4 for 1) else null end ||
case when upper(substring('12E'from 5 for 1)) = lower(substring('12E'from 5 for 1)) then substring('12E'from 5 for 1) else null end ||
case when upper(substring('12E'from 2 for 1)) = lower(substring('12E'from 2 for 1)) then substring('12E'from 2 for 1) else null end
as integer)
Try using this code segment
WHERE id_Field NOT LIKE '%[^0-9]%'
I found lins314159 answer to be very helpful with a similar issue. It may be an old thread but for what it's worth, I used:
char2hexint(upper(id_field)) = char2hexint(lower(id_field)) AND substr(id_field,1,1) IN ('1' to '9')
to successfully cast the remaining VARCHAR results to INT
SELECT customer_id
FROM t
WHERE UPPER(customer_id)(CASESPECIFIC) <>
LOWER(customer_id)(CASESPECIFIC);
This works perfectly fine to check whether the values in a numeric field is non-numeric.
SELECT id_field
WHERE oTranslate(id_field, '0123456789','')<>'';
This works well for me! It reveals any id_field containing a non-numeric value