How to calculate decimal(x, y) max value in SQL Server - sql

How do I know the maximum value of decimal type?
For example:
decimal(5, 2)
Can you please explain the mechanism of decimal type?

The maximum possible value can be calculated using the following maths:
(10 ^ (x-y)) - (10 ^ -y)
So in your initial example
(10 ^ (5-2)) - (10 ^ -2) = 1000 - 0.01 = 999.99
I'm adding this answer as my google results took me here when trying to remind myself how to calculate the SQL friendly upper bounds of a C# decimal going into an SQL (28,10) decimal field.
999999999999999999.9999999999 by the way.

You can use an aggregate function in order to get the maximum value in a column
SELECT MAX(myColumn) AS MyColumnMax
FROM myTable
If you want to know the maximum value for each customer for instance, you can group by this customer
SELECT CustomerID, MAX(OrderAmount) AS MaxOrderAmount
FROM CustomerOrders
GROUP BY CustomerID
You can find other aggregate functions here.
If, by contrast, you are interested in range of a decimal type, then consider, that you are declaring the total number of digits and decimals. Therefore the maximum number is reached, when all these digits are 9.
So for decimal(5,2) it would be 999.99. 5 is the total number of decimals to the left and to the right of the decimal point. 2 is the number of decimals to the right of the decimal point.
The maximum possible range for decimals is -10^38 + 1 through 10^38 - 1.

Related

what is difference between ceiling and roundup server in sql server

What is difference between the Ceiling and Round functions in in SQL Server?
I have some query and I get a totally different value in Round and Ceiling function.
The answer is here
Round does a standard rounding. If value is .5 or over then you get back 1. If it’s less than .5 you get back 0
Ceiling returns the integer equal to or higher than the value passed in.
SELECT ROUND(235.400,0);
Answer= 235.000
SELECT CAST(ROUND(235.400,0) as int)
Answer= 235
Round allows decimal values to round the value.
It will take next value if decimal value is only greater than or equal to 5.
Ceiling no need to decimal values.
It will take the next value of the given number. If decimal value is even less than 5.
ROUND let's you round values in a standard way (round up from values 5 or higher, round down otherwise). It also takes number of decimal places you want to round to, so if you want to get an integer, you just pass 0 as number of decimal places. See documentation.
CEILING is operation, which return the smallest integer greater than passed number, so it rounds up to next integer.
CONLUSION:
So basic difference: CEILING rounds up, while ROUND rounds number in standard way.
Another key difference is that ROUND let's you specify number of decimal places you want round to.

Casting as decimal not acting as expected

I am new to SQL and I am trying to calculate percentage from two pre-calculated numbers. I want the percentage to be at 2 decimal points. The numbers are integers so I am casting them as decimals before the percentage calculation. The calculation is simply
(Risk1/GrandTotal *100) both from the same table.
A piece of the code is given below:
SELECT risk_date_day,
((CAST(Risk1 as decimal(38,2))/CAST(GrandTotal as decimal(38,2))) * 100) FROM DPRAT2_Export
The result shows 6 numbers after the decimal
I have tried many different numbers for the parameters of decimal(x,x). I understood from research that the 2nd number is scale and that specifies the number of places after the decimal. I am not sure why the result has 6 decimal places. Please help. Thanks!
Do the cast() after the division:
SELECT risk_date_day,
CAST(Risk1 * 100.0 / GrandTotal as decimal(38, 2))
FROM DPRAT2_Export;
SQL in general and SQL Server in particular has very arcane rules for determining the number of decimal points in the result of mathematical operations on decimals. So, just convert the result.
If there is the risk that GrandTotal might be zero, I would advise:
SELECT risk_date_day,
CAST(Risk1 * 100.0 / NULLIF(GrandTotal, 0) as decimal(38, 2))
FROM DPRAT2_Export;
This prevents the divide-by-zero error, returning NULL instead.

SSRS format 8.840 to 8.83

I am working on the Report I would like to display the decimal number from 8.84079343397399 to 8.83
Here is my sql query
select (4.83+1.923*LOG10(CAST(c.catchGirth as float))+1.157*LOG10(CAST(c.catchLength as float)))
as estimatesWeight
from Catches c
where c.id =#CatchId
The result is 8.84079343397399
I want the result from 8.84079343397399 to 8.83 or if result 8.84579343397399 to 8.84
SSRS offers the following methods to perform rounding:
Ceiling - Rounds a decimal number up to next whole number (8.84 becomes 9, 8.1 also becomes 9)
Floor - Rounds a decimal number down to whole number (8.84 becomes 8)
Round - At the desired precision, rounds number up if number to right is 5-9 or down if number of right is 0-4 (so Round(8.8402,2) rounds to 8.84, and Round(8.845, 2) rounds to 8.85
Edit
Based on your edit, Round does not offer a Floor at a precision, but assuming the value was in a value called Value, then CDbl(Floor(Value * 100)) / 100.

Sum function doesn't give sufficient decimal places with divide function

I have the following sql query that I am running:
select sum(cast(mkt_value as decimal(20,7)))/1204438043.37 from table1
and I get the following result which is correct but I need at least 10 decimal places not 6:
0.009347
If I run the following query:
select sum(mkt_value) from table1
I get 11258490.2400.
If I divide 11258490.24 by 1204438043.37 in excel I get 0.009347504674 which is the answer I'm looking for.
Please help me correct my SQL!!
Your cast is breaking this. It doesn't have enough space to give you more than six decimal places. What you're saying is literally "give me the result of this division with at most six decimal places", and then you're suprised the result only has six decimal places :)
The solution is either to omit the cast (if the data type is money, it's fine) or increase the scale of the decimal, eg. decimal(20, 11). The second parameter of the decimal type says the maximal amount of decimal places (-1) in the number. Also, consider only casting the result of the sum instead of all the items.
Note that most operations in MS SQL return a value of the same data type. So:
select 3 / 4; -- Returns 0
select cast(1000 as smallint) * cast(1000 as smallint);
-- Error - 1 000 000 is too big for smallint
The same thing happens in your sum and also in the division that happens right after it :)
You need to apply casting after calculating final value
select CAST (sum(mkt_value)/1204438043.37 as decimal(15,10)) from table1.
This means result would be having maximum 15 digits and mandatory 10 decimal places.
I would suggest the following query,Since your final decimal places are getting truncated.Hence a cast would be required to your final result set.
select
cast(cast (sum(mkt_value) as decimal(20,7))/cast (1204438043.37 as decimal(20,7)) as decimal(20,12)) from table1
Thank you..Let me know if this works

Ceiling(convert(decimal,decimalvalue)) vs Ceiling(convert(float,decimalvalue))

When we do Ceiling(convert(decimal,8.09)) then result is 8 and in Ceiling(convert(float,8.09)) result is 9, explain?
A DECIMAL Type in SQL Uses a Precision numeric data type instead of an Approximate numeric data type like a FLOAT. What this implies is that the data stores not only the number but a dimension of how precise it can be, whilst in comparison a float is always a scaled approximation store for a numeric value.
There are 3 pieces to the DECIMAL precision, the value, the P number (for precision) and S number (for scale). The P number is the maximum number of digits that the data type can store so if I have a DECIMAL with a precision of 4 I can only go upto 9999 or as low as 0.001. The default is 18 digits.
The problem you are having is your S number. The S number is the precision of the numbers after the decimal point, a sort of sub-set maximum on top of the P number. So a S precision of 2 means I can have .01 to .99, precision of 4 is .0001 to .9999 and so on. This in combination with P can lead to truncation if you don't account for the maximum digits. So although a conversion of the number 12345.12345 (P,S) = (6,3) should have the 3 decimal digits (12345.123), the maximum digits are 6 so you end up with (12345.1) In order to have an S number the P number must also be declared:
DECIMAL(P[,S])
In this way, due to the construction limits of P and S, P cannot be smaller than S and S not smaller than 0 (you cannot have 14 decimal places in a number which the maximum digits is only 5) :
P >= [S] >= 0
To solve your problem, when you do your CONVERT, declare how precise you need your decimal to be as, by default, the S value is set to 0 :
SELECT CONVERT(DECIMAL(18,6), 8.09)
Here are a few examples to show the precision, run them and see how they work:
SELECT CONVERT(DECIMAL(10,1) , 12.345678) --10 Maximum Digits, 1 Decimal Places (Expect round off)
SELECT CONVERT(DECIMAL(18,3) , 12.2345) --18 Maximum Digits, 3 Decimal Places (Expect 3rd decimal round up)
SELECT CONVERT(DECIMAL(3,4) , 123.456789) --3 Maximum Digits, 4 Decimal Places (Expect 4th decimal round up, but get overflow error as P < S )
SELECT CONVERT(DECIMAL(18,6) , 8.09) --18 Maximum Digits, 6 Decimal Places (Expect no data change in precision)
I hope that helps you out, if possible always use decimal and specify a precision where you know there are bounds. It can be more efficient depending on the data and nature of the procedure.
This is a precision issue.
Because
convert(decimal,8.09) == 8
whereas
convert(float,8.09) == 8.09
decimal has a default precision of 18
float is float(53) (also a synonym for double) which has 15 digit precision
What are you actually trying to do? What is the context?