SQL loses decimals after multiplication - sql

I have a table which includes:
COUNT RISK
35 0.6456000000
11 0.5234000000
4 0.8431000000
I need a column to multiply the two columns. However I'm getting the result of:
TOTAL
35
11
4
COUNT - INT
RISK - VARCHAR
SQL is clearly rounding up the decimals as 1. I've tried casting as decimal, numeric and multiplying by 1.0. I need to retain the decimals for an actual calculation. Any help would be great

Convert result to decimal like this
SELECT
CONVERT(DECIMAL(16,10), COUNT * RISK) AS DecimalResult
FROM dbo.whatever;
Or convert COUNT to decimal
SELECT CAST(COUNT AS DECIMAL(16,10)) * RISK

This question is really suspicious. From the surface, it seems the two columns [Count] and [Risk] have different data types with [Count] as integer and [Risk] as decimal or float.
According to BOL, decimal/float data type has higher precedence, I will quote the BOL here
When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence. If the conversion is not a supported implicit conversion, an error is returned. When both operand expressions have the same data type, the result of the operation has that data type
So to me, in SQL Server, when you do
Select [Total]=[Count]*[Risk] from [your_table]
You cannot get the result as shown in the original question.

Related

PostgreSQL- Round REAL data type (yes, I know numeric exist)

I know REAL data type is not accurate and normally for currency I should use numeric data type.
But, I'm asked to do some stuff and one of the conditions is that the data type is real.
When I try to do round((....),2) for example, I get that round function does not exist for this data type.
My question is, without converting, is there any function that can return a REAL value rounded to 0?
Many thanks!1
As you can see here it's no way to round without any type cast. It's only two kinds of function exists:
round(dp or numeric) - round to nearest integer
round(v numeric, s int) - round to s decimal places
Real = double precision. So you need to use convert anyway if you want to get some decimal places:
select round('123.456789'::real::numeric,2)
upd. Keep care about rounding+cast at big real numbers:
select round('12122156.567'::real::numeric, 2); --< rounding up to 6 digits, result = 12122200
select round('12122156.567'::real::DOUBLE PRECISION::numeric,2); --<< rounding result = 12122157
Or you can use round without decimal places:
select round('123.456789'::real)
round a numeric value to 0 after the dot?
ROUND(numeric_value, 0)
After investigation, converting to ::numeric is the only way around

SQL Division precision

I have 2 columns which I need to divide sum(cola)/sum(ColB), but I am not getting the desired results since SQL server seems to truncate values after decimal
For eg. I have-
select 281370/1035
is giving 271 using simple division, whereas actual result of division is 271.8550724637681 and I want to display 271.8
I tried
SELECT cast(round(281370/1035,1) as numeric(36,1))
but that results 271.0
In SQL Server, you have to cast the integers to decimal and you could use Round to get desired precision.
SELECT cast(Round(CAST(281370 AS decimal) / CAST(1035 AS decimal),1,1) as decimal(10,1))
The problem is that you given the int number and want a decimal result
try this
select convert(decimal(30,10),281370.0/1035.0)
or
select Round(convert(decimal(30,10),281370.0/1035.0),1,1)
#Stormcloak gives the answer to specifically wanting a single position as a mantissa, however to return an exact answer you could "simply" implicitly change the datatype.
select 281370.0/1035
Returns:
271.855072
In Presto DB:
select (CAST(11 as decimal(8,6))/CAST(7 as decimal(8,6))) as result
result:1.571429
decimal(xp,xs)
xp--> total number of digits(before decimal point+ after decimal
point)
xs--> number of digits after the decimal point
reference: https://prestodb.io/docs/current/functions/decimal.html

Trying to sum two columns in SQL Server results in error message

I'm trying to calculate the sum of two separate fields with the query
select sum(percent12 + percent21) as total
from finalquery
but I keep getting this error:
Msg 8117, Level 16, State 1, Line 535
Operand data type varchar is invalid for sum operator.
However, if I do:
select percent12 + percent21 as total
from finalquery
I get:
(total)
50.0040.00
25.0025.00
100.0 0.00
100.0 0.00
100.0 0.00
How can I fix this?
Both of your percentage columns are a varchar, the + operator can concatenate strings together, and that is what you're seeing.
I would suggest that you use a CAST to a NUMERIC data type, especially as it seems that you have a fixed amount of spaces after the decimal.
Try the following:
SELECT
SUM(CAST(percent12 AS NUMERIC(10,2))+ CAST(percent21 AS NUMERIC(10,2))) AS total
FROM finalquery
Others have suggested that you CAST to a FLOAT, though that has known rounding errors (and known workarounds)
Float rounding error: SQL Server rounding Error, Giving different values
It seems that the values you are trying to sum are varchar/string type and therefore they cannot be summed up.
Try convert them to integer or float (depending of the type) before summing
ie at SQL Server Select sum(convert(float,x1) + convert(float,x2) )
When you are using the + operator in your second query, you are actually concatenating two strings. You know they are strings because the error message tells you it's a varchar (i.e. a string).
Instead, you need to convert each field into a number data type and then wrap those in your aggregation. In this case, I chose to cast it as a decimal data type based off of your sample data, but you can cast as integer or other numeric data type as well.
SELECT SUM(CAST(percent12 AS DECIMAL(10, 4)) + CAST(percent21 AS DECIMAL(10, 4))) AS total
FROM finalquery
Of course, the obvious answer is to stop storing numbers as strings. If you can modify your database schema, seriously look into changing that.
Fix your schema and you will solve this problem and prevent many others in the future. You should choose the appropriate datatype for each column - don't just blindly select some type of string because it's "easier".

SQL - Convert number to decimal

I'm trying to convert a number to a decimal with two decimals places.
SELECT CONVERT(DECIMAL(10,2),12345)
The above would return 12345.00 but I'm trying to achieve 123.45
You need something like that:
SELECT CONVERT(DECIMAL(15,2),12345/100.0)
SELECT CONVERT(DECIMAL(10,2),CAST(12345 as float)/CAST(100 as float))
Correction: The premise is somewhat flawed, as the data type of a literal number without a decimal point is int, not numeric as implied by the question. In that case, you do need to convert the initial value to either numeric or decimal before dividing:
SELECT CONVERT(DECIMAL,12345)/100
or
SELECT CAST(12345 AS DECIMAL)/100
(cast is the SQL standard, so if you ever want to apply this to other databases, it would be the preferred method.)
Alternately, you can just add a decimal point to the divisor, as SQL server will return the more precise data type when doing arithmetic on heterogeneous types:
SELECT 12345/100.0
According to the documentation, the numeric data type is functionally equivalent to the decimal datatype, so there's really no reason to convert between the two. It seems that all you really want to do is divide the value you have by 100:
SELECT 12345/100

Change the result to decimal in sql server

I need to change the result of aggregate function in SQL Server 2012 to decimal
M1 and M2 are two columns in my table and their data type is int.
I need to find sum(M1)/sum(M2) and the result should be in 2 decimal places.
How can I achieve this?
I believe you need to cast both to decimals. The result will then be a decimal without other inferred type conversions
cast(sum(M1) as decimal(9,2))/cast(sum(M2) as decimal(9,2))
Precision, Scale, and Length (Transact-SQL)
You need to convert the values before division. Please, read BOL article Data Type Precedence
CAST(SUM(M1) as DECIMAL(10,2))/CAST(SUM(M2) as DECIMAL(10,2)