В стиле SQL - 4 (округление копеек)
Apr. 12th, 2014 04:04 pmВот еще задача из реальной жизни: округление копеек. Путь имеется отчет, показывающий какие-то денежные показатели; суммы надо выводить с точностью до копеек.
Для наглядности возьмем что-нибудь совсем тривиальное. Например, распределим общие затраты (расходы на электроэнергию) на все подразделения компании пропорционально их численности:
with depts(dept_id, quantity) as ( select 1, 300 from dual union all select 2, 300 from dual union all select 3, 100 from dual union all select 4, 100 from dual union all select 5, 100 from dual ), expenditures(amount) as ( select 1000 from dual ), report(dept_id,amount) as( select d.dept_id, e.amount * ratio_to_report(d.quantity) over () from depts d, expenditures e ) select dept_id, round(amount,2) amount from report;
DEPT_ID AMOUNT ------- ------ 1 333,33 2 333,33 3 111,11 4 111,11 5 111,11
Какая досада, копеечка-то потерялась! Бухгалтер, работающий с РСБУ, этого не переживет.
Чтобы получилось правильно, надо учесть ошибки округления. Обычно их собирают вместе и добавляют к строке с максимальной суммой.
Чисто процедурных решений мне на практике не попадалось, но страшненький код видел и даже в детстве сам писал. Например, можно загнать еще не округленные результаты отчета в таблицу и поиздеваться над ней:
declare total number; new_total number; max_dept number; begin select round(sum(amount),2) into total from tmp; update tmp set amount = round(amount,2); select sum(amount) into new_total from tmp; if total = new_total then return; end if; select dept_id into max_dept from tmp where amount = ( select max(amount) from tmp ) and rownum = 1; update tmp set amount = amount + total - new_total where dept_id = max_dept; end; /( А одной командой SQL? )