Rounded decimal truncating small values - rounding up - sql-server

I have, for instance, 1000 tomatoes that costs a total of $4.00. This would be 0.004 per tomato. My data type is a decimal (9,2).
If I wanted to round that value up to 0.01, how would I accomplish that?

Select Round(CEILING(0.004 * 100)/100,2)

select case
when cast(4.00/1000 as decimal(9,2)) < 0.01 then 0.01
else cast(4.00/1000 as decimal(9,2))
end

This should do it:
select ceiling(0.004*100)/100

Related

SQL Server rounding discrepancy

I have a rounding discrepancy in SQL that I could do with a hand resolving.
I have 2 SQL calculations, the first one equals 1.1 and the second 5.65 (see below)
round((sum((monthly_markup)+100) / 100) / sum(monthly_qty),2) as timesby, --equals 1.1
sum(monthly_buy)/sum(monthly_qty) as buy, -- equals 5.65
If I then take those calculations and do calc1 x calc2 it equals 6.21
cast (round(sum(monthly_buy)/sum(monthly_qty) * (sum((monthly_markup)+100) / 100) / sum(monthly_qty),2) as decimal (30,2)), -- equals 6.21 !!
But I am expecting 6.22, as per the below calculation
cast (round((5.65 * 1.1),2) as decimal (30,2)) -- equals 6.22
How can I get my calculation to return 6.22?
Thanks
In case it helps anyone else, I resolved by casting the sum of buy * qty to decimal first.
round((cast(sum(monthly_buy)/sum(monthly_qty) as decimal (5,3)) * round((sum((monthly_markup)+100) / 100) / sum(monthly_qty),2)),2)

SQL Server Decimal Operation is Not Accurate

When I run this simple operation in SQL server:
Select 800.0 /30.0
I get the value 26.666666, where even if it rounds for 6 digits it should be 26.666667.
How can I get the calculation to be accurate? I tried to search about it online and I found a solution where I cast each operand to a high precision decimal before the operation, but this will not be convenient for me because I have many long complex calculations. think there must be a better solution.
When a using division, in SQL Server, any digits after the resulting scale are truncated, not rounded. For your expression you have a decimal(4,1) and a decimal(3,1), which results in a decimal(10,6):
Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
Scale = max(6, s1 + p2 + 1)
As a result, 26.66666666666666~ is truncated to 26.666666.
You can get around this by can increasing the size of the precision and scale, and then CONVERT back to your required precision and scale. For example, increase the precision and scale of the decimal(3,1) to decimal(5,2) and convert back to a decimal(10,6):
SELECT CONVERT(decimal(10,6),800.0 / CONVERT(decimal(5,3),30.0));
This returns 26.666667.
This might helpful:
Use ROUND (Transact-SQL)
SELECT ROUND(800.0 /30.0, 5) AS RoundValue;
Result:
RoundValue
26.666670
I believe it's because SQL Server takes your numbers as decimal values (which are exact e.g., 6.6666 and 6.6667 means exactly those values, not 6 and two-thirds) rather than float values (which can work with approximate numbers).
If you explicity cast/convert it to a float at the start, you should get your calculations running smoothly.
Here's some examples to demonstrate the difference between int, decimal, and float calculations
Dividing 20 by 3
Dividing 20 by 3, then multiplying by 3 again (which mathematically should be 20).
SELECT (20/3) AS int_calc,
(20/3) * 3 AS int_calc_x3,
(CAST(20 AS decimal(10,3)) /3) AS dec_calc,
(CAST(20 AS decimal(10,3)) /3) * 3 AS dec_calc_x3,
(CAST(20 AS float) /3) AS float_calc,
(CAST(20 AS float) /3) * 3 AS float_calc_x3
with the following results
int_calc int_calc_x3 dec_calc dec_calc_x3 float_calc float_calc_x3
6 18 6.666666 19.999998 6.66666666666667 20
In your case, you can use
Select CAST(800.0 AS float) /30.0
which results in 26.6666666666667
Note if you then multiply back by 30, it gets the correct result e.g.,
Select (CAST(800.0 AS float) /30.0) * 30
results in 800. Solutions dealing with decimals will not have this.
Note also that once you have it as a float, then it should stay a float until converted back to a decimal or an int somehow (e.g., saved in a table as an int). So...
SELECT A.Num / 30
FROM (Select ((CAST(800.0 AS float) /30.0) * 30) AS Num) AS A
will still result in 26.6666666666667
This will hopefully help you in your long complex calculations.

Division with different numeric types

I am trying to calculate a rate by using two variables from a subquery and i want my result to have three values after the decimal.
Variables:
calls -- type(integer)
boxes -- type(float)
ROUND((calls / boxes) * 100.0, 3) Call_Rate
only returns two decimal points
when i use
(CAST(calls AS DECIMAL(10,3)) / (boxes AS DECIMAL(10,3)) * 100.0 Call_Rate
this code returns three digits after the decimal but the third digit is always 0, so it is being rounded.
When converting both variables to float, it also returns just 2 values after decimal.
Is there any way to perform this operation to have it return 3 decimal points.
(CAST(calls AS DECIMAL(10,5)) / (boxes AS DECIMAL(10,5)) * 100.0 Call_Rate
When you multiply by 100, you are shifting the decimal point to the right two places, so you need two more places in your decimal conversion.
The 1st calculation actually rounds to three digits, but you probably run this query from SQL Assistant and there's a default precision of two. You can change it in Tools > Options > Number of decimal places to display for Float columns
The result of the 2nd calculation is based on Teradata's calculation rules for decimals, see DECIMAL Result Data Type
In short: Multiply first, then divide
100 * CAST(calls AS DECIMAL(10,3)) / CAST(boxes AS DECIMAL(10,3)) AS Call_Rate
Or keep the Float and do a final cast:
cast( 100 * calls / boxes as decimal(10,3))

Cast function in SQL server

Sample data:
1) 0.02500 = 25
2) 1.0000=100
I tried below code but it's converting 0.25 to 30
Select Try_cast(workcountry as decimal (10,2)*100
Multiply first, then cast. This should give you your an expected behavior.
SELECT TRY_CAST(0.02500*100 AS decimal(10,2))
Your problem is the rounding, 0.025 with 2 decimal places rounds to 0.03. You then multiply that by 100 to get 3. Add an extra decimal place and you'll be fine
select try_cast(0.02500 as decimal (10,3)) * 100
You can try this:
declare #workcountry float = 0.025;
select try_cast(#workcountry * 100. as decimal (10,2))

Rounding price based off price + tax result

I have a table in mssql that has price and tax% of items. I've been set with the task of rounding all of the items to where price + tax is equal to the nearest nickle based off of the calculation of (price(tax_percent/100)+price). The problem I'm coming across is that they want to update the price before the calculation to find the best result, for example:
price tax_percent price_tax_included **Result**
1.05 8.25% 1.13 price=1.07(price + tax = 1.15)
1.02 8.25% 1.10 Don't change, already rounded
1.12 8.25% 1.21 price=1.11(Price + tax = 1.20)
I cant figure out the best way to check what to change the price to for the calculation to work out to the nearest nickle as well as round based on if its below .02 or above .03 cents.
Since a nickel is 1/20th of a dollar. The math is simple... go small to lose the precision, and then bring it back up with a rounded amount.
Declare #Amt money = 1.13
select round(#Amt*.2,2)/.2
Returns
1.1500000
You can use Modulo with %
rextester: http://rextester.com/MUJSMD91030
create table nickels (price_tax_included decimal(9,2))
insert into nickels values (1.20),(1.21),(1.22),(1.23),(1.24),(1.25)
select price_tax_included
, toNickels = price_tax_included
+ case when price_tax_included % 0.05 > .02
then 0.05-(price_tax_included % 0.05)
else -1.00*(price_tax_included % 0.05)
end
from nickels

Resources