How to add a leading 0 in sql-server [duplicate] - sql

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

Related

how to repeat characters in a string

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)),

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)

Prepend 0s to string (to specific length) [duplicate]

This question already has answers here:
Formatting Numbers by padding with leading zeros in SQL Server
(14 answers)
Closed 9 years ago.
I have a query where I'm pulling in a check number from the database. The return value needs to always be 9 characters exactly. Most of the check numbers are only 6 characters, so I want to prepend 0s to to the string to ensure it is always exactly 9 characters. Since the check numbers can vary in length, it will be a different number of 0s for each one. What's the most efficient way to do this?
If they're always between 6 and 9 digits, the easiest (and probably best) way to go is using CASE.
SELECT CASE WHEN LEN(CHECK_NUM)= 6 THEN '000' WHEN LEN(CHECK_NUM) = 7 THEN '00'
WHEN
LEN(CHECK_NUM) = 8 THEN '0' ELSE '' END + CHECK_NUM
FROM TABLE
EDIT
In case the original values are numbers (int), try something like this:
SELECT CASE WHEN LEN(CHECK_NUM)= 6 THEN '000' WHEN LEN(CHECK_NUM) = 7 THEN '00'
WHEN
LEN(CHECK_NUM) = 8 THEN '0' ELSE '' END + CAST(CHECK_NUM AS VARCHAR(9))
FROM TABLE1
Take a look at the this SQL Fiddle.

Sorting varchar column by number, character [duplicate]

This question already has answers here:
How to do sorting on irregular Alphanumeric data in postgres sql
(2 answers)
Closed 10 years ago.
I have a varchar column [flat_number] which has some values as
A1A1A
A1A2A
A1A101A
A3A5A
12
A2
A3
I wish to get the results sorted by number and then by characters first
like
12
A2
A3
A1A1A
A1A2A
A1A101A
A3A5A
I have managed to sort it by number (if the column only contains digits 0-9 using regex, I treat it as a number), then I sort it by character, but it dosent seem to work for column values as A1A101A (having multiple combinations of number and character)
CASE
WHEN length(flat_number) < 10 AND flat_number SIMILAR TO '[0-9]+'
THEN
flat_number::int
END
ELSE
NULL
END,
( SELECT COALESCE( match[1], NULL ) FROM regexp_matches( flat_number, '[^0-9]+' ) AS match ),
( SELECT COALESCE( left( match[1], 9), NULL ) FROM regexp_matches( flat_number, '([0-9]+$)' ) AS match )::int
The current query works as
If the column contains only numbers [0-9] I convert it to int and sort it
ElSE, I split the column into 2 parts and try to extract the column character at the start and the number at the end.
Is there a better wait to do so and also make sure the expected output is returned
I think the following will work:
order by (case when flat_number ~ '^[0-9]+$' then 0 else 1 end),
(case when flat_number ~ '^[0-9]+$' then length(flat_number) end),
flat_number
This orders the number first, uses a trick to put them in numeric order, and then orders the rest of the numbers.

how do i filter out non-numeric values in a text field in teradata?

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