SQL Server Concatenate string column value to 5 char long - sql

Scenario:
I have a table1(col1 char(5)); A value in table1 may '001' or '01' or '1'.
Requirement:
Whatever value in col1, I need to retrive it in 5 char length concatenate with leading '0' to make it 5 char long.
Technique I applied:
select right(('00000' + col1),5) from table1;
I didn't see any reason, why it doesn't work? but it didn't.
Can anyone help me, how I can achieve the desired result?

Since you're using a fixed width column, it's already of size 5 (with whitespace). You need to trim it:
DECLARE #table1 TABLE (col1 char(5))
INSERT INTO #table1 (col1) VALUES ('12345')
INSERT INTO #table1 (col1) VALUES ('1')
SELECT RIGHT('00000'+RTRIM(col1),5) FROM #table1
-- Output:
-- 12345
-- 00001
Or use varchar instead:
DECLARE #table2 TABLE (col1 varchar(5))
INSERT INTO #table2 (col1) VALUES ('12345')
INSERT INTO #table2 (col1) VALUES ('1')
SELECT RIGHT('00000'+col1,5) FROM #table2
-- Output:
-- 12345
-- 00001

If you are storing the data in a CHAR field you are probably getting right spaces buffered with blanks. e.g. 01 = "01 ". If your do a RIGHT("00000" + value, 5) it'll still be the original value. You need to do a RTRIM() on the value or store the data in a VARCHAR field.

The problem is that the char(5) field is always 5 characters long, not matter what you put into it. If you insert '01' into the field, the value stored is actually '01 ' (note the trailing spaces).
Try this:
select right(('00000' + replace(col1, ' ', '')), 5)
Edit: I will leave my answer here as an example, but Michael's answer using rtrim is better.

you need to store your data in a consistent manner, so you don't need to write queries to format the data each time. this will fix your existing data:
UPDATE table1
SET col1= RIGHT('00000'+ISNULL(RTRIM(col1),''),5)
now every time you select you only have to do this:
SELECT col1 FROM table1
however, you must make sure that the data is formatted properly (leading zeros) every time it is inserted. I'd add a check constraint just to make sure:
ALTER TABLE table1 ADD CONSTRAINT
CK_table1_col1 CHECK (LEN(col1)=5)
and when you insert do this:
INSERT INTO table1
(col1, ...
VALUES
(RIGHT('00000'+ISNULL(RTRIM(#col1),''),5)

Related

How to convert or cast int to string in SQL Server

Looking at a column that holds last 4 of someone's SSN and the column was originally created as an int datatype. Now SSN that begin with 0 get registered as 0 on the database.
How can I convert the column and it's information from an int into a string for future proof?
You should convert. CONVERT(VARCHAR(4), your_col)
If you specifically want zero-padded numbers, then the simplest solution is format():
select format(123, '0000')
If you want to fix the table, then do:
alter table t alter column ssn4 char(4); -- there are always four digits
Then update the value to get the leading zeros:
update t
ssn4 = format(convert(int, ssn4), '0000');
Or, if you just want downstream users to have the string, you can use a computed column:
alter table t
add ssn4_str as (format(ssn4, '0000'));
If you want to add leading zeros, use:
SELECT RIGHT('0000'+ISNULL(SSN,''),4)
First thing never store SSN or Zip Code as any numeric type.
Second you should fix the underlying table structure not rely on a conversion...but if you're in a jam this is an example of a case statement that will help you.
IF OBJECT_ID('tempdb..#t') IS NOT NULL
BEGIN
DROP TABLE #t
END
GO
CREATE TABLE #t(
LastFourSSN INT
)
INSERT INTO #t(LastFourSSN)
VALUES('0123'),('1234')
SELECT LastFourSSN --strips leading zero
FROM #t
SELECT -- adds leading zero to anything less than four charaters
CASE
WHEN LEN(LastFourSSN) < 4
THEN '0' + CAST(LastFourSSN AS VARCHAR(3))
ELSE CAST(LastFourSSN AS VARCHAR(4))
END LastFourSSN
FROM #t
If you are looking for converting values in the column for your purpose to use in application, you can use this following-
SELECT CAST(your_column AS VARCHAR(100))
--VARCHAR length based on your data
But if you are looking for change data type of your database column directly, you can try this-
ALTER TABLE TableName
ALTER COLUMN your_column VARCHAR(200) NULL
--NULL or NOT NULL based on the data already stored in database

'LIKE' issues with FLOAT: SQL query needed to find values >= 4 decimal places

I have a conundrum....
There is a table with one NVARCHAR(50) Float column that has many rows with many numbers of various decimal lengths:
'3304.063'
'3304.0625'
'39.53'
'39.2'
I need to write a query to find only numbers with decimal places >= 4
First the query I wrote was:
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9]%'
The above code finds all numbers with decimal places >= 2:
'3304.063'
'3304.0625'
'39.53'
Perfect! Now, I just need to increase the [0-9] by 2...
SELECT
Column
FROM Tablename
WHERE Column LIKE '%.[0-9][0-9][0-9][0-9]%'
this returned nothing! What?
Does anyone have an explanation as to what went wrong as well and/or a possible solution? I'm kind of stumped and my hunch is that it is some sort of 'LIKE' limitation..
Any help would be appreciated!
Thanks.
After your edit, you stated you are using FLOAT which is an approximate value stored as 4 or 8 bytes, or 7 or 15 digits of precision. The documents explicitly state that not all values in the data type range can be represented exactly. It also states you can use the STR() function when converting it which you'll need to get your formatting right. Here is how:
declare #table table (columnName float)
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
--see the conversion
select * , str(columnName,20,4)
from #table
--now use it in a where clause.
--Return all values where the last digit isn't 0 from STR() the conversion
select *
from #table
where right(str(columnName,20,4),1) != 0
OLD ANSWER
Your LIKE statement would do it, and here is another way just to show they both work.
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304.0625'),
('39.53'),
('39.2')
select *
from #table
where len(right(columnName,len(columnName) - charindex('.',columnName))) >= 4
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
One thing that could be causing this is a space in the number somewhere... since you said the column type was VARCHAR this is a possibility, and could be avoided by storing the value as DECIMAL
declare #table table (columnName varchar(64))
insert into #table
values
('3304.063'),
('3304. 0625'), --notice the space here
('39.53'),
('39.2')
--this would return nothing
select *
from #table
where columnName like '%.[0-9][0-9][0-9][0-9]%'
How to find out if this is the case?
select *
from #table
where columnName like '% %'
Or, anything but numbers and decimals:
select *
from #table
where columnName like '%[^.0-9]%'
The following is working fine for me:
declare #tab table (val varchar(50))
insert into #tab
select '3304.063'
union select '3304.0625'
union select '39.53'
union select '39.2'
select * from #tab
where val like '%.[0-9][0-9][0-9][0-9]%'
Assuming your table only has numerical data, you can cast them to decimal and then compare:
SELECT COLUMN
FROM tablename
WHERE CAST(COLUMN AS DECIMAL(19,4)) <> CAST(COLUMN AS DECIMAL(19,3))
You'd want to test the performance of this against using the character data type solutions that others have already suggested.
You can use REVERSE:
declare #vals table ([Val] nvarchar(50))
insert into #vals values ('3304.063'), ('3304.0625'), ('39.53'), ('39.2')
select [Val]
from #Vals
where charindex('.',reverse([Val]))>4

VARCHAR Column contains both decimal or Money

I have a varchar column that can either be a money or decimal data type. Sample values stored are 500 & .02 for each example.
How can I test to see if it's Money or a decimal and if it is a decimal add a leading 0 in front of it so the result will be 0.02?
Thanks in advance
Here is how you could convert all of the data to be consistently displayed as the Money datatype.
DECLARE #BadDesign TABLE (
BadDataTyping VARCHAR(100)
)
INSERT INTO #BadDesign (BadDataTyping) VALUES ('500')
INSERT INTO #BadDesign (BadDataTyping) VALUES ('.02')
SELECT * FROM #BadDesign
SELECT CONVERT(MONEY,BadDataTyping) FROM #BadDesign
UPDATE #BadDesign
SET BadDataTyping=CONVERT(MONEY,BadDataTyping)
SELECT * FROM #BadDesign
Maybe it will be helpful for you:
SELECT REPLACE(REPLACE('500 & .02','&',''),' ','')::DECIMAL(15,2); -- result: 500.02 (decimal)
Maybe this is what you're looking for? It takes all values with a leading "." and adds a "0". The search pattern in the 3rd row can be adjusted if you want to identify you're decimal values somehow differently.
SELECT
CASE TRUE
WHEN LEFT( col1, 1 ) = "." THEN CONCAT('0', col1 )
ELSE col1
END AS col1_formatted
FROM tab1

SQL automatically rounding off values

I have two table. First table(Table1) use to get the records and second table(Table2) used to insert first table record into it. But I am little bit confused after getting result.
In table 1 and table 2 column "Amount" have same data type i.e nvarchar(max)
Table1
Id Amount
1 Null
2 -89437.43
2 -533.43
3 22403.88
If I run this query
Insert into Table2(Amount)
Select Amount from Table1
Then get result like this, I don't know why values are automatically rounded off
Table2
Id Amount
1 Null
2 -89437.4
2 -533.43
3 22403.9
SQL Server will round float values when converting back and to from string types.
And then you have the fun bits of empty string being 0, as well other strange effects
SELECT CAST(CAST('' AS float) AS nvarchar(MAX))
SELECT CAST(CAST('0.E0' AS float) AS nvarchar(MAX))
Use decimal.
If you need to store "blank" (how does this differ from NULL?) use a separate bit column to allow that extra value
Here is good explanation about your question.
Eigher you explicitly give float or decimal or numeric(xx,x) (x means numeric value)
Then it will convert as the data, other wise it round off the last value.
Insert into Table2(Amount)
Select cast(Amount as numeric(18,2) --or , cast (Amount as float)
from Table1
Check this link:-
TSQL Round up decimal number
In my case I was doing the conversion to the correct data type but had decimal(18,0) for the column in the table. So make sure the decimal places are represented properly for the column decimal(18,2).
Perhaps it's your query tool that's truncating to 8 characters.
Check the actual fields lengths to see if the problem is really in the database:
SELECT LEN(Amount)
FROM Table2
WHERE Amount LIKE '%-89437.%'
Unreproducible. Running this script on SQL Server 2012:
DECLARE #T1 TABLE ([Amount] nvarchar(max) NULL);
DECLARE #T2 TABLE ([Amount] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount])
VALUES (NULL),('-89437.43'),('-533.43'),('22403.88');
Insert into #T2(Amount)
Select Amount from #T1;
SELECT * FROM #T2;
Produces this result:
Amount
NULL
-89437.43
-533.43
22403.88
The problem you describe does not exist.
This will show you the problem:
DECLARE #T1 TABLE ([Amount123456789] money NULL);
DECLARE #T2 TABLE ([Amount123456789] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount123456789])
VALUES (NULL),('-89437.43123'),('-533.43456'),('22403.88789'),(22403.88789);
Insert into #T2(Amount123456789)
Select Amount123456789 from #T1;
SELECT * FROM #T1;
SELECT * FROM #T2;

SQL CHECK CONSTRAINT VARCHAR

create table table1
(
column1 varchar2(8)
check constraint column1_ch check ........
);
How do I do a check for a data that the first 4 char is a specific set of alphabets while the last 4 is numbers? and as well as a range of values.
examples, data can be ABCD2121, ABCD1111.
range - ABCD0001 to ABCD9999
So 'ABCD' is fixed while the numbers are changing.
I've foudn online about using '[]" to define the numbers but i'm not able to integrate it into my constraint.
Thanks
The easiest way is to do this using a regular expression:
alter table table1
add constraint chck_code check (regexp_like(column1, '(ABCD)[0-9]{4}') );
If you've got a fixed set of prefixes, use regexp_like and enumerate the prefix list:
alter table test_1
add constraint chk_col1 check(regexp_like(column1, '(ABCD|EFGH)[0-9]{4}'));
This will allow ABCD and EFGH as prefixes, followed by exactly 4 digits.
Your check condition should be as follows:
(column1 LIKE 'ABCD[0-9][0-9][0-9][1-9]')
Edit: Modified to use a set prefix vs. a range for the alpha characters.
Here's a solution using Microsoft SQL Server that illistrates this:
DECLARE #MyTable TABLE
(column1 varchar(8) check (column1 LIKE 'ABCD[0-9][0-9][0-9][1-9]'))
INSERT INTO #MyTable (column1)
SELECT 'ABCD0000'
UNION SELECT 'ABCD2121'
UNION SELECT 'ABCD1111';
SELECT *
FROM #MyTable;
INSERT INTO #MyTable (column1)
SELECT 'ABCD000A'; --<== Fails!
INSERT INTO #MyTable (column1)
SELECT 'ABCD221'; --<== Fails!