Convert float into varchar in SQL Server without scientific notation - sql-server

Convert float into varchar in SQL Server without scientific notation and trimming decimals.
For example:
I have the float value 1000.2324422, and then it would be converted into varchar as same 1000.2324422.
There could be any number of decimal values...the float value comes randomly.

Casting or converting to VARCHAR(MAX) or anything else did not work for me using large integers (in float fields) such as 167382981, which always came out '1.67383e+008'.
What did work was STR().

Neither str() or cast(float as nvarchar(18)) worked for me.
What did end up working was converting to an int and then converting to an nvarchar like so:
convert(nvarchar(18),convert(bigint,float))

The STR function works nice. I had a float coming back after doing some calculations and needed to change to VARCHAR, but I was getting scientific notation randomly as well. I made this transformation after all the calculations:
ltrim(rtrim(str(someField)))

Try CAST(CAST(#value AS bigint) AS varchar)

This works:
CONVERT(VARCHAR(100), CONVERT(DECIMAL(30, 15), fieldname))

Try this:
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(REPLACE(CAST(CAST(YOUR_FLOAT_COLUMN_NAME AS DECIMAL(18,9)) AS VARCHAR(20)),'0',' ')),' ','0'),'.',' ')),' ','.') FROM YOUR_TABLE_NAME
Casting as DECIMAL will put decimal point on every value, whether it
had one before or not.
Casting as VARCHAR allows you to use the REPLACE function
First REPLACE zeros with spaces, then RTRIM to get rid of all trailing spaces (formerly zeros), then REPLACE remaining spaces with zeros.
Then do the same for the period to get rid of it for numbers with no decimal values.

This is not relevant to this particular case because of the decimals, but may help people who google the heading.
Integer fields convert fine to varchars, but floats change to scientific notation. A very quick way to change a float quickly if you do not have decimals is therefore to change the field first to an integer and then change it to a varchar.

Below is an example where we can convert float value without any scientific notation.
DECLARE #Floater AS FLOAT = 100000003.141592653
SELECT CAST(ROUND(#Floater, 0) AS VARCHAR(30))
,CONVERT(VARCHAR(100), ROUND(#Floater, 0))
,STR(#Floater)
,LEFT(FORMAT(#Floater, ''), CHARINDEX('.', FORMAT(#Floater, '')) - 1)
SET #Floater = #Floater * 10
SELECT CAST(ROUND(#Floater, 0) AS VARCHAR(30))
,CONVERT(VARCHAR(100), ROUND(#Floater, 0))
,STR(#Floater)
,LEFT(FORMAT(#Floater, ''), CHARINDEX('.', FORMAT(#Floater, '')) - 1)
SET #Floater = #Floater * 100
SELECT CAST(ROUND(#Floater, 0) AS VARCHAR(30))
,CONVERT(VARCHAR(100), ROUND(#Floater, 0))
,STR(#Floater)
,LEFT(FORMAT(#Floater, ''), CHARINDEX('.', FORMAT(#Floater, '')) - 1)
SELECT LEFT(FORMAT(#Floater, ''), CHARINDEX('.', FORMAT(#Floater, '')) - 1)
,FORMAT(#Floater, '')
In the above example, we can see that the format function is useful for us. FORMAT() function returns always nvarchar.

I have another solution since the STR() function would result some blank spaces, so I use the FORMAT() function as folowing example:
SELECT ':' + STR(1000.2324422), ':' + FORMAT(1000.2324422,'##.#######'), ':' + FORMAT(1000.2324422,'##')
The result of above code would be:
: 1000 :1000.2324422 :1000

You can use this code:
STR(<Your Field>, Length, Scale)
Your field = Float field for convert
Length = Total length of your float number with Decimal point
Scale = Number of length after decimal point
For example:
SELECT STR(1234.5678912,8,3)
The result is: 1234.568
Note that the last digit is also round up.

You will have to test your data VERY well. This can get messy. Here is an example of results simply by multiplying the value by 10. Run this to see what happens.
On my SQL Server 2017 box, at the 3rd query I get a bunch of *********. If you CAST as BIGINT it should work every time. But if you don't and don't test enough data you could run into problems later on, so don't get sucked into thinking it will work on all of your data unless you test the maximum expected value.
Declare #Floater AS FLOAT =100000003.141592653
SELECT CAST(ROUND(#Floater,0) AS VARCHAR(30) ),
CONVERT(VARCHAR(100),ROUND(#Floater,0)),
STR(#Floater)
SET #Floater =#Floater *10
SELECT CAST(ROUND(#Floater,0) AS VARCHAR(30) ),
CONVERT(VARCHAR(100),ROUND(#Floater,0)),
STR(#Floater)
SET #Floater =#Floater *100
SELECT CAST(ROUND(#Floater,0) AS VARCHAR(30) ),
CONVERT(VARCHAR(100),ROUND(#Floater,0)),
STR(#Floater)

There are quite a few answers but none of them was complete enough to accommodate the scenario of converting FLOAT into NVARCHAR, so here we are.
This is what we ended up with:
DECLARE #f1 FLOAT = 4000000
DECLARE #f2 FLOAT = 4000000.43
SELECT TRIM('.' FROM TRIM(' 0' FROM STR(#f1, 30, 2))),
TRIM('.' FROM TRIM(' 0' FROM STR(#f2, 30, 2)))
SELECT CAST(#f1 AS NVARCHAR),
CAST(#f2 AS NVARCHAR)
Output:
------------------------------ ------------------------------
4000000 4000000.43
(1 row affected)
------------------------------ ------------------------------
4e+006 4e+006
(1 row affected)
In our scenario the FLOAT was a dollar amount to 2 decimal point was sufficient, but you can easily increase it to your needs.
In addition, we needed to trim ".00" for round numbers.

Try this code
SELECT CONVERT(varchar(max), CAST(1000.2324422 AS decimal(11,2)))
Result:
1000.23
Here decimal(11,2): 11-total digits count (without the decimal point), 2 - for two digits after the decimal point

None of the previous answers for me. In the end I simply used this:
INSERT INTO [Destination_Table_Name]([Field_Name])
SELECT CONCAT('#',CAST([Field_Name] AS decimal(38,0))) [Field_Name]
FROM [dbo].[Source_Table_Name] WHERE ISNUMERIC([CIRCUIT_NUMBER]) = 1
INSERT INTO [Destination_Table_Name]([Field_Name])
SELECT [Field_Name]
FROM [dbo].[Source_Table_Name] WHERE ISNUMERIC([CIRCUIT_NUMBER]) <> 1

select format(convert(float,#your_column),'0.0#########')
Advantage: This solution is independent of the source datatype (float, scientific, varchar, date, etc.)
String is limited to 10 digits, and bigInt gets rid of decimal values.

This works:
Suppose
dbo.AsDesignedBites.XN1E1 = 4016519.564`
For the following string:
'POLYGON(('+STR(dbo.AsDesignedBites.XN1E1, 11, 3)+'...

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 do I do decimal arithmetic on two varchars and return result to an aliased column?

I have two fields of type varchar that contain numeric values or blank strings, the latter of which I have filtered out to avoid Divide by Zero errors.
I am attempting to determine the percentage value that num2 represents in relation to num1, i.e. (Num_2 * 1 / Num_1). Relatively simple math.
The problem I am having is that I cannot seem to do the math and then cast it to a decimal value. I keep receiving Arithmetic overflow error converting int to data type numeric errors.
Can someone help me out with the casting issue?
You didn't interpret the error correctly.
It is not about casting the result of your math to float, it is about implicit type casting before the equation is evaluated.
You have in your table some values that cannot be converted to numeric, because they are not valid numbers or numbers out of range. It is enough that one row contains invalid data to make fail the whole query.
perhaps you're looking for something similar to this?
declare #table table (
[numerator] [sysname]
, [denominator] [sysname]);
insert into #table
([numerator],[denominator])
values (N'1',N'2'),
(N'9999999999',N'88888888888');
select case
when isnumeric([numerator]) = 1
and isnumeric ([denominator]) = 1
then
cast([numerator] as [float]) / [denominator]
else
null
end
from #table;
Is this what you're looking for?
select cast('25.5' as decimal(15, 8)) / cast('100.0' as decimal(15, 8))
The example above will return this:
0.25500000000000000000000
In this case, I'm converting the operand types before they get used in the division.
Remember to replace the literals in my query by your field names.
you said that can be number or blank string.
son try something like this:
SELECT
(CASE WHEN NUM_2 = '' THEN 0 ELSE CAST(NUM_2 AS NUMERIC(15,4)) END)
/
(CASE WHEN NUM_1 = '' THEN 1 ELSE CAST(NUM_1 AS NUMERIC(15,4)) END)
you test if string is blank. if it is, you use 0 (or 1, to avoid division by zero)

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