Question

I am wondering how Oracle sums NUMBER(9,2) with SUM(numWithScale/7).

This is because I am wondering how the error will propagate with a large amount of records

Let's say I have a table EMP_SAL with some EMP_ID, numWithScale, numWithScale being a salary.

To make it simple, let us make the numWithScale column NUMBER(9,2) 9 decimals of precision with 2 decimals to round to. All of these numbers in the table are random digits from 10.00-20.00 (ex. 10.12, 20.00, 19.95)

I divide by 7 in my calculation to give random digits at the end that round up or down.

Now, I sum all of the employees salaries with SUM(numWithScale/7).

Will the sum round each time it adds a record? Or does Oracle round after the calculation is complete? i.e. the error can be +/-0.01 from rounding, and with many additions then roundings, error adds up. Or does it round at the end? Thus I dont have to worry about the error adding up (unless I use the result in many more calculations)

Also, will Oracle return the sum as the more precise NUMBER, (38 digit precision, floating point)? or will it round up to the second digit NUMBER(9,2) when returning the value?

Will MSSQL behave pretty much the same way (even though syntax is different?

Was it helpful?

Solution

Oracle performs operation in the order you specified.

So, if you write this query:

select SUM(numWithScale/7) from some_table -- (1)

each of values divided by 7 and rounded to maximum available precision: NUMBER with 38 significant digits. After that all digits are summed.

In case of this query:

select SUM(numWithScale)/7 from some_table -- (2)

all numWithScale values are summed and only after that divided by 7. In this case there are no precision loss for each record, only result of sum() division by 7 are rounded to 38 significant digits.

This problem are common for calculation algorithms. Each time when you divide value by 7 you produce small calculation error because of limited number of digits, representing a number:
numWithScale/7 => quotient + delta.
While summing this values you got
sum(quotient) + sum(delta).

If numWithScale represents ideal uniform distribution and and a some_table contains infinite number of records, then sum(delta) tends to zero. But it happens only in theory. In practical cases sum(delta) grows and introduces significant error. This is a case of query(1).

On the other hand, summing can't introduce a rounding error if implemented properly. So for query (2) rounding error introduced only in last step, when whole sum divided by 7. Therefore value of delta for this query not affected by number of records.

OTHER TIPS

Number scale and precision is only relevant as column or variable constraint.

When you attempt to store a number that exceeds defined precision it will raise an exception:

create table num (a number(5,2));
insert into num values (123456.789);
=> ORA-01438: value larger than specified precision allowed for this column

When you attempt to store a number that exceeds defined scale it will be rounded:

insert into num values (123.456789);
select a from num;
=> 123.46

Precision and scale do not matter when you read data and perform any calculations on it...

select 100000 + a / 100 from num;
=> 100001.2346

...unless you want to store it back into column with constraints, so above rules apply:

update num set a = a / 100;
select a from num;
=> 1.23

numWithScale/7 will be converted to NUMBER (i.e. it will not be rounded to number(9,2)).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top