SQL Server adding trailing zeros to result of division - sql-server

Has anyone encountered the following where when you divide a number in SQL a random number of trailing zeros are appended?...
SELECT 8.95/10 ... results in 0.895000
If you have encountered this, what is the reason for the addition of the zeros?
UPDATE: I am aware that casting the result to FLOAT will remove the 0's

First of all, seeing trailing zeros or anything when querying in SSMS is not because it's something special with the DB engine, but it's always the result of the internal query result formating used for displaying. After all, all numbers are just binary values in some representation that at some point gets translated to strings for displaying.
Anyway, the real reason is because of the datatypes involved, and how SSMS decides to display them. When doing those calculations, SQL Server must decide what datatype the result will be, based on the types of the inputs, and in that particular case it was numeric(7,6). You can easily see the result types by saving the result to a temp table and running sp_columns on that:
SELECT 8.95 AS dividend,10 AS divider,8.95/10 AS result INTO #temp ;
EXEC tempdb..sp_columns '#temp' ;
SELECT * FROM #temp ;
DROP TABLE #temp ;
In my case it returned this (among other uninteresting things for now):
COLUMN_NAME TYPE_NAME PRECISION LENGTH SCALE
dividend numeric 3 5 2
divided int 10 4 0
result numeric 7 9 6
Playing with castings in various places in the division will only change the resulting data types. The interesting fact is the Scale for the result column, note that it's a 6. That's exactly the number of decimal places that SSMS decides to display for the NUMERIC data type, regardless of the actual value. FLOAT don't have this formating from SSMS, which is why the casting eliminates the trailing zeros. Of course, when using the DB from outside SSMS, the formating will depend on the calling application and will not be subject to all this.
As another example of this behavior, just try SELECT CAST(1 AS NUMERIC(18,10)) and see that it shows 1.0000000000.

Related

SQL server , We have one column of the data decimal(38,35) truncating when we are using cast and float in sql server

We have one column in sql server where we need to consider the all the digits as it is transaction table.The column data type like decimal(38,35) ,its appending zeroes when in sql server like the value is 1.2369 but its displaying as 1.236900000000000000.. but it can be restricted by using float and cast like
"select cast(cast('1.2369'as decimal(38,35))as float)" it will truncate all the zeroes but the real question is when we use the same expression for the bigger decimal value like 1.236597879646479444896645 its truncate the trailing values,considering only up-to scale of 15 digits,if anybody finds the logic for this one please help me .Thank you and
Note :The values are always dynamic.
Becouse float has a precision of 15 digits.
See documentation: float and real
To format a DECIMAL(38,35) without insignificant zeroes, use an explicit FORMAT string, e.g.
SELECT FORMAT(1.23690000000000000, '0.' + REPLICATE('#', 35))
gives 1.2369 (SQL Server 2012 and up). Note, however, that the resulting type is a string, not a number, and so this should only ever be done as the final step (and only if your client software isn't smart enough to format the values on its own). While you're calculating with it, there is either no need to cut off digits, or else you need to be explicit about it by converting to the appropriate DECIMAL (e.g. 1.2369 fits in a DECIMAL(5, 4)). SQL Server can't do this automatically because it doesn't know what kind of precision you're going for in your calculations, but it is definitely something you must take into account, because combining DECIMALs of different scale and precisions can give unexpected results when you're close to the edge.
If you want to remove trailing 0s, recognize that this is now string formatting, not any numeric processing. So we'll convert it to a string and then trick RTRIM into doing the job for us:
select REPLACE(
RTRIM(
REPLACE(
CONVERT(varchar(40),convert(decimal(38,35),'1.2069'))
,'0',' '))
,' ','0')
As I said in a comment though, it's usually more appropriate to put these presentation concerns in your presentation layer, rather than doing it down in the database - especially if whatever is consuming this result set wants to work with this data numerically. In that case, leave it alone - the trailing zeroes are only their because that's how management studio chooses to format decimals for display.

Arithmetic overflow error for type int, value = 4957500001.400178

I know that similar questions have been asked again in the past, but I think my case is slightly different. I have a column which has Logarithmic values and I'm trying to invert them using the following formula:
SELECT POWER(10,CAST(9.695262723 AS NUMERIC(30,15)))
Let's say the value 9.695262723 is one of the values of that column.
When trying to run this query I get an Arithmetic overflow error for type int, value = 4957500001.400178.
On the other hand, the same query works fine for smaller values e.g. SELECT POWER(10,CAST(8.662644523 AS NUMERIC(30,15)))
How could I overcome that error and calculate the inverse values of the log10 entries I have? Just for information the greater value that exists in the table (in log10 scale) is 12.27256096.
The problem here is your first input parameter (10) which SQL server will, by default, treat as the datatype int.int has a maximum value of 2^31-1 (2,147,483,647), and the number 4,957,500,001 is far larger than this, so you need to use a bigint:
SELECT POWER(CONVERT(bigint,10),CONVERT(numeric(30,15),9.695262723));
Edit: If you need to retain the decimal places, then use a numeric with a large enough scale and precision, instead of bigint.

Obtaining decimal values in calculations in database

Recently, I came across an anomaly that while dividing two integers, I am getting only the quotients and reminders are simply ignored.
SELECT 12/8,12%8
The above query gives 1 and 4 respectively, which is similar to Java/C programming. Again applying Java/C programming methods used below calculations to obtain the expected value.
SELECT 12.0/8,12/8.0
The answer is 1.5000 and 1.5000 respectively.
Working on my task I got a situation to obtain percentage value across two counted values (integers) and I stuck up with the results similar to the former query. Then I worked out through the same by multiplying one of the value with 1.0 . This solved my issue.
But later on, going through few scripts, used in my project (developed long back), I noticed in certain cases the decimal values are returned from the query even though two counted values (whole numbers) are divided.
I first noticed this in Netezza. But same holds true in SQL Server as well.
Please advise on what basis the datatypes of returned values are decided.
When dividing both integers, it will perform integer division, which returns an integer. To perform floating point division, you must either cast one or both of the operands to float/decimal/double.
SELECT cast(12 as float)/8
SELECT 12/cast(8 as float)
SELECT cast(12 as float)/cast(8 as float)
SELECT cast(12/8 as float)
Note that the last query is different since the integer division is performed first before casting to float,that is why the decimal value was already lost.

SQL Server : SUM() weird behaviour

I run this example in SQL Server Management Studio:
SELECT CONVERT(REAL, -2101.12) n INTO #t
SELECT * FROM #t
SELECT SUM(n) FROM #t
The first SELECT creates a temp table #t with 1 column n of type real, and it puts 1 row in it with the value -2101.12.
The second SELECT confirms that the table is created with the intended content and the result is:
n
---------
-2101.12
The third SELECT sums the only number that is there, but the result is:
-2101.1201171875
So the question is: Where the 0.0001171875 comes from?
EDIT: I know the lack of precision for the real and float data types, unfortunately I cannot change the database schema because of this. What surprise me though, is that I would expect to see also the extra decimals in the second select since it is supposed to be stored with that lack of precision. Since it does not happens on the second select, then why the sum function picks it up?
You've just discovered real (aka floating point) data is approximate.
Use decimal datatype instead.
The FLOAT and REAL data types are known as approximate data types. The behavior of FLOAT and REAL follows the IEEE 754 specification on approximate numeric data types.
Approximate numeric data types do not store the exact values specified for many numbers; They store an extremely close approximation of the value. For many applications, the tiny difference between the specified value and the stored approximation is not noticeable. At times, though, the difference becomes noticeable. Because of the approximate nature of the FLOAT and REAL data types, do not use these data types when exact numeric behavior is required, such as in financial applications, in operations involving rounding, or in equality checks. Instead, use the integer, decimal, money, or smallmoney data types.
Avoid using FLOAT or REAL columns in WHERE clause search conditions, especially with the = or <> operators. It is best to limit FLOAT and REAL columns with > or < comparisons.
Source of above statement

Query number of decimal places in a sql server resultset

I have a table which contains a field of type numeric(28,10). I would like to display the records with a monospaced font, and a matching number of decimal places so that they line up when right aligned.
Is there any way to figure out the maximum number of decimal places that can be found in a given result set so that I can format accordingly as I display each record?
Edit: sorry, I should have been clearer ... if the result set contains numbers with only 3 decimal places, then all of the numbers should have only 3 decimal places (padded with zeroes).
The monospaced font is entirely a presentation issue...
I don't see your need for right alignment when I test:
CREATE TABLE [dbo].[Table_1](
[num] [numeric](28, 10) NOT NULL
)
INSERT INTO [example].[dbo].[Table_1] VALUES (1.1234567890);
INSERT INTO [example].[dbo].[Table_1] VALUES (1.123456789);
INSERT INTO [example].[dbo].[Table_1] VALUES (1.1234567);
SELECT [num]
FROM [example].[dbo].[Table_1]
...returns:
num
---------------
1.1234567890
1.1234567890
1.1234567000
So the question is--what are you trying to do that isn't giving you the output you desire?
Where do you want to display the results? Query Analyzer? In an application?
You can either
a) format the column to have a
finite number (known in advance) of
digits to the right of the decimal
point, truncating at that position;
this is the typical practice or
b) read through all of the rows in the
resultset to determine the value
with the greatest number of digits
to the right of the decimal point
(casting to string, splitting the
value using the decimal point as
delimiter, and getting the length of
the decimal-fraction string)
If for some reason option a) is unacceptable then you'd have do do b) procedurally, either server-side in a stored procedure or client-side in your client program.

Resources