Brandon Moore
Brandon Moore

Reputation: 8780

More concise way to cast division of integers to decimal

I'm trying to divide some integers to get a percentage. By default I get an integer result, of course, so I cast to decimal. But I also would like the result to only have two places to the right of the decimal.

--select (x - y) / y

select (82 - 56) / 56                                      --0
select (82 - 56) / cast(56 as decimal(9, 2))               --0.4642857142
select cast(82 - 56 as decimal(9,2)) / 56                  --0.464285
select cast((82 - 56) / 56 as decimal(9,2))                --0.00

select cast(cast(82 - 56 as decimal) / 56 as decimal(9,2)) --.46

So I end up having to cast both one of the operands and the entire expression in order to get the result I want. Is there a better way to do this?

Notice I put the equation up top to signify that I am obviously not working with hardcoded numbers (i.e. Suggesting I just put ".0" after the numbers would be less than helpful). Also, I would normally leave the formatting aspect to reporting software, but this is being copied from time to time into an excel spreadsheet and I would have to hand format it every time.

Upvotes: 0

Views: 3559

Answers (1)

Quassnoi
Quassnoi

Reputation: 425431

When dividing a DECIMAL by an INTEGER, SQL Server yields a DECIMAL with precision defined as p1 - s1 + s2 + max(6, s1 + p2 + 1), where sn and pn are the scale and the precision of the 1st and 2nd arguments (the divident and the divisor).

The simplest way would be:

SELECT  CAST(1. * (x - y) / y AS DECIMAL(9, 2))

1. is a DECIMAL(1, 0) which, being multiplied by an integer, yields a DECIMAL(n, 0). Being divided by an integer, it would then yield a DECIMAL(n, 6) (for the number orders similar to those in your example).

It then needs to be cast to DECIMAL(9, 2) to truncate the extra digits.

Upvotes: 3

Related Questions