Round 916.984800 to 916.99 - sql-server

Is it possible to round 916.984800 to 916.99 in SQL Server?
I've tried as below but I don't want '+ 0.1' as my solution.
Round((((424.53 - 0) * 36) * (6 / 100)),2) + .01 as [Amount]
or
Round((((424.53 - 0) * 36) * (0.06)),2) + .01 as [Amount]
Thanks

This produces expected output:
SELECT CEILING((424.53 - 0) * 36 * 0.06 * 100) / 100 AS [Amount]
Amount
----------
916.990000
What happens?
SELECT (424.53 - 0) * 36 * 0.06 * 100
This returns 91698.4800, CEILING returns the smallest integer greater than, or equal to, the specified numeric expression, in your case 91699, and later I just divide it by 100, which brings expected result.

Related

Rounding Down number to the 60

How can I round a number to interval of 60 ?
For instance if I have number 61, It should round of to 60 and if number is 150, it should round of to 120 and in case of 59 it should round off to zero.
To truncate values multiply by 60 and divide by 60. See demo:
SELECT 61/60*60 --result: 60
SELECT 59/60*60 --result: 0
Number must be int (bigint, smallint, tinyint). If it's not, use CAST/CONVERT.
See also Division (Transact SQL):
If an integer dividend is divided by an integer divisor, the result is
an integer that has any fractional part of the result truncated.
ugly but it works:
Integer Division Then Multiply
SELECT (125 / 60 ) * 60
Think this is what you're after
DECLARE #TestVal INT = 59
SELECT #TestVal - (#TestVal % 60)
SET #TestVal = 61
SELECT #TestVal - (#TestVal % 60)
SET #TestVal = 150
SELECT #TestVal - (#TestVal % 60)
Alternative is to use the modulus operator to get the remainder of a division by 60 then subtract it:
% (Modulus) (Transact-SQL)
Returns the remainder of one number divided by another.
For example:
declare #valueToTest int = 150
select #valueToTest - (#valueToTest % 60) as result
-- result: 120
So this gets the remainder when you divide the #valueToTest by 60 and subtracts it from the original #valueToTest.
I'd prefer FLOOR over relying on Integer division, it's what FLOOR is for. example
DECLARE #YourVal DECIMAL(10,4) = 220.1234;
SELECT #YourVal / 60 * 60, FLOOR(#YourVal / 60) * 60;

How scale is defined when decimal and bigint are divided?

I have value A of type DECIMAL(19,8) - the scale is 8, so the number of decimal digits that will be stored to the right of the decimal point is 8.
Now, I am dividing A on B, where B is BIGINT. For, example:
SELECT CAST(3 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 0.111111111111111111111111111
,CAST(300 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT) -- 11.111111111111111111111111111
,CAST(75003 AS DECIMAL(19, 8)) / CAST(13664400 AS BIGINT) -- 0.005488934750153684025643277
the output values are with length: 29, 30, 29 respectively.
Could anyone tell why the length of the value for the three divisions is not 30? How the SQL Server is calculating the scale of the final result?
Argument 1: 3 AS DECIMAL(19, 8)
Argument 2: 27 AS DECIMAL (18, 0) -- default precision is 18, default scale is 0 (BIGINT was converted to DECIMAL due to type precedence)
p1 = 19
p2 = 18
s1 = 8
s2 = 0
max precision = (p1 - s1 + s2) + MAX(6, s1 + p2 + 1) -- up to 38
max scale = MAX(6, s1 + p2 + 1)
Let's calculate for example 1:
precision: (19 - 8 + 0) + MAX(6, 8 + 18 + 1) = 38
scale: MAX(6, 8 + 18 + 1) = 27
For all your examples you will get always max 27 scale.
0.111111111111111111111111111 (27)
11.111111111111111111111111111 (27)
0.005488934750153684025643277 (27)
The whole part takes only necessary digits (1), (2), (1).
For me everything is perfectly valid.
This answer is based on work of #Paul White from Decimal Truncation In division.
This is call Data Type Precedence.
When a query do something between different but yet compatible types, one of them has to be casted to the other type, eitheir with an explicit or implicit conversion.
If you look at Data Type Conversion (Database Engine)
, you will see that there is an implicit conversion between Decimal and Bigint.
Therefore you query does not requiere an explicit cast.
If you look at Data Type Precedence (Transact-SQL) on MSDN, you will see:
decimal
bigint
This means that decimal has a higher precedence than bigint and the bigint value will converted to decimal.
In the end, you calculation will be:
3,000... / 27,000...
300,000... / 27,000...
75003,000... / 27,000...
If you want it to be 3 / 27, you must do an explicit cast on the Decimal value.

Rounding down decimal numbers in SQL Server 2008

I read all rounding functions of T-SQL like Round, Floor, and Ceil, but none of them has rounded down decimal numbers correctly for me.
I have 2 questions:
How to round down a decimal number (3.69 ==> 3.5)?
How to round up the last 3 digits of an integer (e.g. 142600 ==> 143000)?
1) select CAST(FLOOR(2 * 3.69) / 2 AS decimal(2, 1)) handles the first case - courtesy of an answer to a similar question on SQL Server Forums, which I adapted and quickly checked.
Note that if the numbers you are rounding to the nearest 0.5 could be bigger (e.g. 333.69 => 333.5), be sure to specify more decimal precision when you cast (e.g. select CAST(FLOOR(2 * 3.69) / 2 AS decimal(10, 1))), or you could get an overflow error:
Msg 8115, Level 16, State 8, Line 1
Arithmetic overflow error converting numeric to data type numeric.
Extra precision will not affect the bottom-line result (i.e. select CAST(FLOOR(2 * 3.69) / 2 AS decimal(10, 1)) and select CAST(FLOOR(2 * 3.69) / 2 AS decimal(2, 1)) both yield 3.5); but it is wasteful if the numbers you are rounding will always be smaller.
Online references with examples are available for T-SQL FLOOR, CAST, and decimal to help.
2) select ROUND(142600, -3) handles the second case.
A similar online reference is available for T-SQL ROUND.
As per #J0e3gan 's anwser, Sql Server's Round allows rounding to the nearest powers of 10 using the length parameter, where length is 10^(-length), e.g.
length = 0 : 10 ^ 0 = nearest 1
length = 3 : 10 ^ -3 = nearest .001
length = -3 : 10 ^ 3 = nearest 1000
etc
However, in general, with a simple 1-based rounding function - e.g. (Sql Round with Length=0) to round to an arbitrary value of "nearest N" - with the formula:
round(X / N) * N
e.g. nearest 100
select round(12345 / 100.0, 0) * 100.0 -- 12300
select round(-9876 / 100.0, 0) * 100.0 -- -9900
select round(-9849 / 100.0, 0) * 100.0 -- -9800
... Nearest 0.5
select round(5.123 / 0.5, 0) * 0.5 -- 5.000
select round(6.499 / 0.5, 0) * 0.5 -- 6.500
select round(-4.499 / 0.5, 0) * 0.5 -- -4.50
... Nearest 0.02
select round(5.123 / .02, 0) * .02 -- 5.12
select round(-9.871 / .02, 0) * .02 -- -9.88
etc
Remember that the type used for the divisors must be numeric / decimal or float.
The Oracle/PLSQL FLOOR function returns the largest integer value that is equal to or less than a number.
eg:
FLOOR(7.9)
Result: 7
FLOOR(30.29)
Result: 30
FLOOR(-7.9)
Result: -8

Database calculations are wrong

Here is what I'm setting:
result = price / (case when tax = 0 then #tax1h / 100 else #tax2 / 100 end + 1)
These are the values:
price = 17.5
tax = 1
tax2 = 6
17.5 / (6 / 100 + 1) = 16.5
And this returns 17.5 Why is this happening and how to solve it?
Integer division:
select (6 / 100 + 1)
The result of the above is 1.
However, the result of:
select (6 / 100.0 + 1)
Is 1.06.

Decimal to HH:MM Conversion

I have a table and I want to update the Duration column which of datatype Decimal to HH:MM format.
ECode Duration
101 101.75
101 69.56
102 54.60
103 54.97
The output should be like this:
ECode Duration
101 102.15
101 69.56
102 55
103 55.37
We are calculating the time after the decimal and if after decimal 60 or more then 60 will be there we are adding 1 before decimal and remaining after subtraction from 60 we are showing as it is.
Example 101.75, here after decimal 75 is there so firstly we check it is greater than or equal to 60. If yes then subtract 60 and add 1 before decimal and put the remaining 15 after decimal. So the result should be 102.15.
Please share query if possible to solve this issue.
This should do it:
update thistable
set duration = duration + 0.4
where duration - floor(duration) >= 0.6
update YourTable set
Duration = floor(Duration) +
cast(((Duration - floor(Duration))*100) as int) / 60 +
cast((cast((Duration - floor(Duration)) * 100 as int) % 60) as float) / 100
I guess you would do something like ("pseudo" code of some sort):
String reorder(String x) {
String parts[] = x.split(.);
if(parts.length < 2) x;
// eval as integers:
if(parts[1] < 60) return x;
if(parts[1] > 60) return (parts[0]+(parts[1]/60))+"."+(parts[1]%60);
return parts[0]+1;
}
But exactly how you do it depends whether you're doing in a script, some application and the language you're using...

Resources