我需要将1个金额拆分为2个字段。我知道结果字段的总和=分割第一行的比率,但我需要舍入结果总和,然后才计算下一行的比率(所以舍入的总和价值观是正确的。)
如何在Oracle 10g PL / SQL中编写此算法?我需要测试一些迁移的数据。这是我想出的(到目前为止):
with temp as (
select 1 id, 200 amount, 642 total_a from dual union all
select 2, 200, 642 from dual union all
select 3, 200, 642 from dual union all
select 4, 200, 642 from dual union all
select 5, 200, 642 from dual
)
select
temp2.*,
remaining_a / remaining_amount ratio,
round(amount * remaining_a / remaining_amount, 0) rounded_a,
round(amount - amount * remaining_a / remaining_amount, 0) rounded_b
from (
select
temp.id,
temp.amount,
sum(amount) over (
order by id
range between current row and unbounded following
) remaining_amount,
case when id=1 then total_a /* else ??? */ end remaining_a
from temp
) temp2
更新 :如果您看不到上面的图片,预期舍入_A 值为:
1 128
2 129
3 128
4 129
5 128
答案 0 :(得分:3)
这是我的建议。它没有得到你想要的。 。 。根据我的计算,129直到第3行才会出现。
想法是添加更多列。对于每一行,计算估计的分割。然后,跟踪累积分数。当暨余数超过一个整数时,然后将A金额提高1.一旦你有A金额,你可以计算其余的:
WITH temp AS (
SELECT 1 id, 200 amount, 642 total_a FROM dual UNION ALL
SELECT 2, 200, 642 FROM dual UNION ALL
SELECT 3, 200, 642 FROM dual UNION ALL
SELECT 4, 200, 642 FROM dual UNION ALL
SELECT 5, 200, 642 FROM dual
)
select temp3.*,
sum(estArem) over (order by id) as cumrem,
trunc(estA) + (case when trunc(sum(estArem) over (order by id)) > trunc(- estArem + sum(estArem) over (order by id))
then 1 else 0 end)
from (SELECT temp2.*,
trunc(Aratio*amount) as estA,
Aratio*amount - trunc(ARatio*amount) as estArem
FROM (SELECT temp.id, temp.amount,
sum(amount) over (ORDER BY id range BETWEEN CURRENT ROW AND unbounded following
) remaining_amount,
sum(amount) over (partition by null) as total_amount,
max(total_a) over (partition by null)as maxA,
(max(total_a) over (partition by null) /
sum(amount) over (partition by null)
) as ARatio
FROM temp
) temp2
) temp3
这不是一个分区问题。这是整数近似问题。
如果你要对值进行四舍五入而不是截断它们,那么你需要稍微调整逻辑。
trunc(estA) + (case when trunc(sum(0.5+estArem) over (order by id)) > trunc(0.5 - estArem + sum(estArem) over (order by id))
这句话最初只是寻找通过整数阈值的累积余数。这应该进行舍入而不是截断。