TSQL Decimal To Text - sql-server

I have the following field called - Amount. It's a decimal(18,2).
So a value of 70.26
What I want to create for the sake of a file out is something like -
00000007026
Where it's a varchar (11), with leading zeros to make up the 11 characters, if only 4 exist in the example above, but also I want the decimal removed as well

You can try something like this :
SELECT RIGHT('00000000000' + REPLACE(CAST(Amount AS VARCHAR(11)),'.',''),11)
Explanation
The CAST transforms the number into a string, for further manipulations.
The REPLACE removes the decimal point.
The I add 11 zeros, no matter what will be the number here. But taking only 11 characters from the RIGHT, will give what you want.
This will not work for negative numbers, as the zeros will be added at the left of the - sign.

declare #str varchar(11)
set #str='00000000000'
declare #p decimal(18,2)
set #p=70.80
select RIGHT(#str+replace(cast(#p as varchar),'.',''), 11 )

Related

Way to show items where more than 5 decimal places occur?

I am trying to filter out some query results to where it only shows items with 6 decimal places. I don't need it to round up or add 0's to the answer, just filter out anything that is 5 decimal places or below. My current query looks like this: (ex. if item is 199.54215 i dont want to see it but if it is 145.253146 i need it returned)
select
TRA_CODPLANTA,
TRA_WO,
TRA_IMASTER,
tra_codtipotransaccion,
tra_Correlativo,
TRA_INGRESOFECHA,
abs(tra_cantidadparcial) as QTY
from mw_tra_transaccion
where FLOOR (Tra_cantidadparcial*100000) !=tra_cantidadparcial*100000
and substring(tra_imaster,1,2) not in ('CP','SG','PI','MR')
and TRA_CODPLANTA not in ('4Q' , '5C' , '5V' , '8H' , '7W' , 'BD', 'DP')
AND tra_INGRESOFECHA > #from_date
and abs(tra_cantidadparcial) > 0.00000
Any assistance would be greatly appreciated!
Here is an example with ROUND, which seems to be the ideal function to use, since it remains in the realms of numbers. If you have at most 5 decimal places, then rounding to 5 decimal places will leave the value unchanged.
create table #test (Tra_cantidadparcial decimal(20,10));
INSERT #test (Tra_cantidadparcial) VALUES (1),(99999.999999), (1.000001), (45.000001), (45.00001);
SELECT * FROM #test WHERE ROUND(Tra_cantidadparcial,5) != Tra_cantidadparcial;
drop table #test
If your database values are VARCHAR and exist in the DB like so:
100.123456
100.1
100.100
You can achieve this using a wildcard LIKE statement example
WHERE YOUR_COLUMN_NAME LIKE '%.[0-9][0-9][0-9][0-9][0-9][0-9]%'
This will being anything containing a decimal place followed by AT LEAST 6 numeric values
Here is an example using a conversion to varchar and using the LEN - the CHARINDEX of the decimal point, I'm not saying this is the best way, but you did ask for an example in syntax, so here you go:
--Temp Decimal value holding up to 10 decimal places and 10 whole number places
DECLARE #temp DECIMAL(20, 10) = 123.4565432135
--LEN returns an integer number of characters in the converted varchar
--CHARINDEX returns the integer location of the decimal where it is found in the varchar
--IF the number of characters left after subtracting the index of the decimal from the length of the varchar is greater than 5,
--you have more than 6 decimal places
IF LEN(CAST(#temp AS varchar(20))) - CHARINDEX('.', CAST(#temp AS varchar(20)), 0) > 5
SELECT 1
ELSE
SELECT 0
Here is a shorthand way.
WHERE (LEN(CONVERT(DOUBLE PRECISION, FieldName % 1)) - 2) >=5
One way would be to convert / cast that column to a lower precision. Doing this would cause automatic rounding, but that would show you if it is 6 decimals or not based on the last digit. If the last digit of the converted value is 0, then it's false, otherwise it's true.
declare #table table (v decimal(11,10))
insert into #table
values
(1.123456789),
(1.123456),
(1.123),
(1.123405678)
select
v
,cast(v as decimal(11,5)) --here, we are changing the value to have a precision of 5. Notice the rounding.
,right(cast(v as decimal(11,5)),1) --this is taking the last digit. If it's 0, we don't want it
from #table
Thus, your where clause would simply be.
where right(cast(tra_cantidadparcial as decimal(11,5)),1) > 0

SQL Server stored procedure conversion decimal point without rounding to two decimal

Decimal point conversion without rounding to two decimal
My variable is of datatype varchar, so I have to convert it to numeric. But what the thing is my output value is 0.0012499987 and I want the output as 1.24 i.e. without rounding the value.
This is my code
Set #SQLQuery = #SQLQuery + 'CAST((ISNULL(CAST(DI.Coupon AS NUMERIC(18,4)),0) * 100) AS Varchar(50)) AS Coupon,
Here I have to multiply with 100 don't remove that; di.coupon is of type varchar. Keep it in your mind
And the result value also I want as a varchar.
Please someone help me
Sample input / output
0.013923 1.39
You can use CAST
EDIT: I added an ISNULL
DECLARE #N
SET #N = '0.013923'
SELECT CAST(CAST(CAST(ISNULL (#N, 0) AS DECIMAL(38,18)) * 100 AS DECIMAL(18,2)) AS VARCHAR (50))
Probably the easiest is to get the substring of the original column and cast that to numeric. Then it will drop the remaining digits.
In SQL Server, LEFT(column, 4) will do what you want.
But as #HABO pointed out, the in-built function Round() will accept a parameter that truncates the decimal value.
I have got the answer for this. This might help for some people
cast(left(('00122.45678')*100,instr(('00122.45678')* 100,'.','1')+3)as varchar) as stb
Output:
122.456
If you want for 2 decimal without round of then you can add like +2 instead of +3

Remove the trailing zeros after Decimal points without truncating/ approximating the value in SQL server

Have decimals stored as varchar.
I have a column with value 0.0375000. I need to convert this into 0.0375.
When I did
convert(decimal(8, 7), substring(column, 0, 1) + '.' + substring(column, 2, 8)))
I got the result as 0.0375000.
I want to remove all the trailing zeros and the result I want is 0.0375
How can I do this?
If 2012+ The #'s indicate an optional display
Select format(0.0375000,'0.######') Returns 0.0375
Select format(0.037502,'0.######') Returns 0.037502
Sorry didn't see stored as varchar()
Select format(cast(somecolumn as decimal(18,8)),'0.######')
if you only need 4 decimal places, you want decimal 5,4 (assuming your number to the left of the decimal point fits into 1 digit , if you need 2 digits, choose decimal(6,4) for example )
select convert(decimal(5,4), substring(column,0,1)+'.' +substring(column,2,8) )
decimal data type https://msdn.microsoft.com/en-gb/library/ms187746.aspx
--SQL Code for easy removing trailing zeros.
select CONVERT(DOUBLE PRECISION,'2.256000')
--Result will be 2.256

How to add leading zeros to decimal value in tsql

i have weight column in a table where weight must be inserted with following format '09.230'. Weight column is of varchar type. so value from front end comes as '9.23' it should get converted to above mentioned format i.e.(09.230). I am able to add trailing zero but adding leading zero is a problem.
This is what i have done to add trailing zero
CAST(ROUND(#Weight,3,0) AS DECIMAL (9,3))
Suppose #Weight = 6.56 output with above comes out be '6.560' but output wanted as '06.560'.
RIGHT('0'+ CONVERT(VARCHAR, CAST(ROUND(#Weight,3,0) AS DECIMAL (9,3))), 6)
This
takes your expression,
converts it to a varchar (retaining the trailing zeros, since the source data type was decimal),
adds a 0 in front of it, and
trims it to 6 characters by removing characters from the front, if needed (e.g. 012.560 -> 12.560, but 06.560 -> 06.560).
Do note, though, that this only works for numbers with at most two digits before the decimal point: 100.123 would be truncated to 00.123!

How to get the count of digits after the decimal point in a float column in ms sql?

I have to count the digits after the decimal point in a database hosted by a MS Sql Server (2005 or 2008 does not matter), in order to correct some errors made by users.
I have the same problem on an Oracle database, but there things are less complicated.
Bottom line is on Oracle the select is:
select length( substr(to_char(MY_FIELD), instr(to_char(MY_FILED),'.',1,1)+1, length(to_char(MY_FILED)))) as digits_length
from MY_TABLE
where the filed My_filed is float(38).
On Ms Sql server I try to use:
select LEN(SUBSTRING(CAST(MY_FIELD AS VARCHAR), CHARINDEX('.',CAST(MY_FILED AS VARCHAR),1)+1, LEN(CAST(MY_FIELD AS VARCHAR)))) as digits_length
from MY_TABLE
The problem is that on MS Sql Server, when i cast MY_FIELD as varchar the float number is truncated by only 2 decimals and the count of the digits is wrong.
Can someone give me any hints?
Best regards.
SELECT
LEN(CAST(REVERSE(SUBSTRING(STR(MY_FIELD, 13, 11), CHARINDEX('.', STR(MY_FIELD, 13, 11)) + 1, 20)) AS decimal))
from TABLE
I have received from my friend a very simple solution which is just great. So I will post the workaround in order to help others in the same position as me.
First, make function:
create FUNCTION dbo.countDigits(#A float) RETURNS tinyint AS
BEGIN
declare #R tinyint
IF #A IS NULL
RETURN NULL
set #R = 0
while #A - str(#A, 18 + #R, #r) <> 0
begin
SET #R = #R + 1
end
RETURN #R
END
GO
Second:
select MY_FIELD,
dbo.countDigits(MY_FIELD)
from MY_TABLE
Using the function will get you the exact number of digits after the decimal point.
The first thing is to switch to using CONVERT rather than CAST. The difference is, with CONVERT, you can specify a format code. CAST uses whatever the default format code is:
When expression is float or real, style can be one of the values shown in the following table. Other values are processed as 0.
None of the formats are particularly appealing, but I think the best for you to use would be 2. So it would be:
CONVERT(varchar(25),MY_FIELD,2)
This will, unfortunately, give you the value in scientific notation and always with 16 digits e.g. 1.234567890123456e+000. To get the number of "real" digits, you need to split this number apart, work out the number of digits in the decimal portion, and offset it by the number provided in the exponent.
And, of course, insert usual caveats/warnings about trying to talk about digits when dealing with a number which has a defined binary representation. The number of "digits" of a particular float may vary depending on how it was calculated.
I'm not sure about speed. etc or the elegance of this code. it was for some ad-hoc testing to find the first decimal value . but this code could be changed to loop through all the decimals and find the last time a value was greater than zero easily.
DECLARE #NoOfDecimals int = 0
Declare #ROUNDINGPRECISION numeric(32,16) = -.00001000
select #ROUNDINGPRECISION = ABS(#ROUNDINGPRECISION)
select #ROUNDINGPRECISION = #ROUNDINGPRECISION - floor(#ROUNDINGPRECISION)
while #ROUNDINGPRECISION < 1
Begin
select #NoOfDecimals = #NoOfDecimals +1
select #ROUNDINGPRECISION = #ROUNDINGPRECISION * 10
end;
select #NoOfDecimals

Resources