Division of two values returning 0 rather than positive or negative decimal - sql

I have a large stored procedure updating a table each night. It grabs a basic amount of information in to a temp table before updating each of the remaining columns through a series of updates.
One of these updates is a division. The division takes two previously updated fields and divides them.
UPDATE C
SET C.RETURN_ON_SALES = C.TW_UNIT_SALES / C.DISTRIBUTION
FROM
#custTop150 C
The column definitions in #custTop150 are as follows:
RETURN_ON_SALES DECIMAL(5,2) NULL
TW_UNIT_SALES INT NULL
[DISTRIBUTION] INT NULL
All of my results for this update are returning as 0.00. To give you an example of some of the divisions it is calculating:
7 / 41 | Returns 0.00 when it should return 0.17073170731
11 / 41 | Returns 0.00 when it should return 0.26829268292
9 / 41 | Returns 0.00 when it should return 0.21941219512
5 / 38 | Returns 0.00 when it should return 0.13157894736
I know that the answer will be pretty simply or right in front of my eyes but at this point in time I am completely lost as to why this is happening.
Thanks

Guess you are working on SQL Server. Then change RETURN_ON_SALES to Decimal(10,10) and CAST the inputs or change its data type to DECIMAL
DECLARE #RETURN_ON_SALES decimal(10,10);
DECLARE #TW_UNIT_SALES INT ;
DECLARE #DISTRIBUTION INT ;
SET #TW_UNIT_SALES=7;
SET #DISTRIBUTION=41;
SET #RETURN_ON_SALES=CAST(#TW_UNIT_SALES AS DECIMAL (10,5))/ CAST (#DISTRIBUTION AS DECIMAL(10,5));
PRINT #RETURN_ON_SALES;

TRY THIS: It seems your columns are defined as INTEGER and in the division it should return in DECIMAL value so for this we can simply change the one of operand value to DECIMAL using CAST and it will return the DECIMAL value as below
DECLARE #first INT = 4, #second INT = 3
SELECT #first/#second -- OUTPUT: 1
SELECT #first/CAST(#second AS DECIMAL(10,5)) -- OUTPUT: 1.33333333333333

Try this:
UPDATE C
SET C.RETURN_ON_SALES = 1.0 * C.TW_UNIT_SALES / C.DISTRIBUTION
FROM
#custTop150 C
Note that the 1.0 will cause a cast to float before assigning to the target variable.
You are not specifying which DBMS so, to make sure it works, you may also try the following (if the previous still does not work):
UPDATE C
SET C.RETURN_ON_SALES = (1.0 * C.TW_UNIT_SALES) / (1.0 * C.DISTRIBUTION)
FROM
#custTop150 C

Related

Strange result when dividing two numbers

This code:
DECLARE #remise decimal(10,2)
set #remise = 10 / 100
select #remise
results in 0.00. Why doesn't it result in 0.10, which I have been expecting?
You have two integers - 10 and 100. So when considering the division operator, the system decides to perform integer division. Integer division disregards any remainder and cannot produce a decimal result, so the result is 0.
It doesn't matter that you're subsequently planning to store the result in a decimal(10,2).
One way to solve it would be to use a non-integer as one of the inputs to the division. If you're not using literals, commonly this can be done by multiplying one of the inputs by 1.0:
DECLARE #remise decimal(10,2)
set #remise = (10 * 1.0) / 100
select #remise
Is this SQL Server?
10 and 100 are both integers. The integer division 10 / 100 results in 0. If you put that 0 into a decimal variable, the zero still stays zero.
You want
DECLARE #remise decimal(10,2)
set #remise = 10.0 / 100.0
select #remise

SQL 2017 rounds of decimal number using "FLOOR" function

I have been calculating different integer percentages with different numbers but each time I get floor rounded number. select 13*100/60 gives me 21 and the actual number is 21.66 which using a round function should give us 22 but it can only give me 21 for all different decimal numbers.
I am using SQL 2017. please help
This is due to the fact that you are dividing ints and not floating-point numbers. Integer division returns an integer.
Try the following instead (noting the .0 on the end of the 60):
SELECT 13 * 100 / 60.0
Making one of the components a floating-point number will automatically output the result as a floating-point number.
Output:
21.666666
Incidentally, if you are working with variables and one of them is a FLOAT, it will automatically produce the output you expect:
DECLARE #A FLOAT
DECLARE #B INT
DECLARE #C INT
SET #A = 13
SET #B = 100
SET #C = 60
SELECT #A * #B / #C
Output:
21.6666666666667

Round off to the smallest integer value

I'm using this query to round off the numbers and this round off the next value. Now I need to round off to the before value means if the value is 45.67 then the value should be 45. I tried these two queries and still I need to tweak the values.
Method1:
parsename('$' + convert(varchar,convert(money,round(sum(Column1 * Column2),0)),1),2)
Method2:
parsename('$' + convert(varchar,convert(money,floor(Column1 * Column2),0),1),2)
Really appreciate any suggestions.
The CEILING function returns the smallest integer greater than or equal to the specified numeric expression. The FLOOR function returns the largest integer less than or equal to the specified numeric expression. For example, in considering a numeric expression of 12.9273, CEILING returns 13 and FLOOR returns 12. The return value of both FLOOR and CEILING has the same data type as the input numeric expression.
SELECT CEILING(12.9273);
Here is the result set.
13
SELECT FLOOR(12.9273);
Here is the result set.
12
http://technet.microsoft.com/en-us/library/ms190927%28v=sql.105%29.aspx
To round down you can use FLOOR()
E.G.
DECLARE #number numeric(5,2)
SET #number = 45.67
SELECT FLOOR(#number)
You'd get the result 45
With your example, it looks like it's already working?
declare #number1 numeric(5,2)
declare #number2 numeric(5,2)
set #number1 = 1.23
set #number2 = 21.69
select parsename('$' + convert(varchar,convert(money,floor(#number1 * #number2),0),1),2)
select #number1 * #number2
Results
$26
26.6787

CEILING returns FLOOR result - SQL SERVER 2008 R2

DECLARE #a int;
DECLARE #b int;
SET #a = 9;
SET #b = 2;
SELECT CEILING (#a/#b);
It is returning as 4 instead of 5. Why?
Edit: I would like to get next smallest integer if the quotient is not whole number.
Try:
SELECT CEILING (#a/CAST(#b AS float))
And consider NULLIF(#b,0) too, to avoid a Division By Zero error.
After dividing 9 by 2 a decimal fraction is Truncated to its integer part - 4, not Rounded to 5. Try:
SELECT 9/2
Resilt is 4. Then CEILING(4) = 4
To get next integer declare variables as data types that can handle decimal part: NUMERIC,FLOAT, REAL.
SQL Server does integer division. So 9/2 = 4 in SQL Server.
Taking the ceiling of an integer is the same integer.

SQL floating-point precision limited to 6 digits

I have the following set of calculations in excel that I want to be able to use in a stored procedure.
Excel
CellA: 45/448.2 = 0.100401606425703
CellB: 1-CellA = 0.899598393574297
CellC: 1-CellB = 0.100401606425703
CellD: CellC * 448.2 = 45.000000000000000
In SQL I am doing the following:
declare #a decimal(18,15) = 45/448.2
declare #b decimal(18,15) = 1-#a
declare #c decimal(18,15) = 1-#b
declare #d decimal(18,15) = #c * 448.2
I have also tried running the calculation in one line
declare #e decimal(18,15) = (1-(1-(45/448.2)))*448.2
when I return the values SQL gives me the following:
#a: 0.100401000000000
#b: 0.899599000000000
#c: 0.100401000000000
#d: 44.999728200000000
#e: 44.999728200000000
I've tried adjusting the precision of the decimals in SQL but I nothing makes a difference, it only returns the first 6 digits of the decimal.
Does Excel do any optimization when running the formula?
Any ideas?
Even just your first line is enough to show the problem:
declare #a decimal(18,15) = 45/448.2
print #a
gives
---------------------------------------
0.100401000000000
This is because of data types. When you say
448.2
it is (per the documentation) interpreted as a constant of type decimal, and also per the documentation,
In Transact-SQL statements, a constant with a decimal point is
automatically converted into a numeric data value, using the minimum
precision and scale necessary. For example, the constant 12.345 is
converted into a numeric value with a precision of 5 and a scale of 3.
So 448.2 is decimal(4,3). 45 is integer, which when combined with a decimal is treated as having precision of 10 and scale 0 . When we divide, the rules say
Operation Result precision Result scale
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
which in this case gives a result precision of 10 - 3 + 0 + max(6, 0 + 3 + 1) and scale of max(6, 0 + 3 + 1), which comes out to 13 and 6.
That result scale of 6 is why the result only has those six decimal places.
The way to fix it is to get your operands into an appropriate type before acting on them; for example, here are two ways:
Force a number to be treated as floating-point:
declare #a decimal(18,15) = 45/448.2e0
select #a
---------------------------------------
0.100401606425703
Explicitly supply a decimal scale:
declare #a decimal(18,15) = 45/cast(448.2 as decimal(18,10))
select #a
---------------------------------------
0.100401606425703