我想在PL / SQL中进行prorata
计算,但我不知道如何做到这一点。
这是我的例子:
ID class Wages Premium
1 A 15000 250
2 A 10000 0
我想在课堂上按比例计算保费,即对于每个CLASS中的每个ID,我想按照工资计算保费。
这里,对于ID 1, 它会:
premium = (15000 *sum(premium))/(sum(wages)) = (15000 * 250)/(25000) = 150
因此,对于ID 2:
premium = (10000 * 250)/(25000) = 100
显然我必须在更大量的数据上做到这一点......但到目前为止我还没有做太多的PL / SQL ......
我可以补充一点,我必须做一个更新声明......
请你能帮帮我吗?
非常感谢
答案 0 :(得分:2)
最有效的方法是使用ratio_to_report(),这通常会被奇怪地忽略。
select id,
premium,
sum(premium) over (partition by class) *
ratio_to_report(wages) over (partition by class) prorated_premium
from my_table
有关更新,我会看一下:
update (query from above)
set premium = prorated_premium
答案 1 :(得分:1)
您可以使用分析函数轻松计算新的溢价值:
create table prorata_test as
select 1 id,
'A' class,
15000 wages,
250 premium
from dual
union all
select 2 id,
'A' class,
10000 wages,
0 premium
from dual
union all
select 3 id,
'B' class,
10000 wages,
50 premium
from dual;
select id,
class,
wages,
premium,
sum(wages) over (partition by class) tot_wages,
sum(premium) over (partition by class) tot_premium,
wages * sum(premium) over (partition by class) / sum(wages) over (partition by class) new_premium
from prorata_test;
ID CLASS WAGES PREMIUM TOT_WAGES TOT_PREMIUM NEW_PREMIUM
---------- ----- ---------- ---------- ---------- ----------- -----------
1 A 15000 250 25000 250 150
2 A 10000 0 25000 250 100
3 B 10000 50 10000 50 50
因此,您可以看到计算tot_wages和to_premium列的分析和函数总结了每个类的值(我们将其分区(也称为分组)),因此您只需在new_premium中使用它们即可。计算
要存储新的高级值,您可以使用带有上述查询的MERGE语句作为源数据集,如下所示:
merge into prorata_test tgt
using (select id,
class,
wages,
premium,
wages * sum(premium) over (partition by class) / sum(wages) over (partition by class) new_premium
from prorata_test) src
on (tgt.id = src.id)
when matched then
update set tgt.premium = src.new_premium;
commit;
select *
from prorata_test
order by id;
ID CLASS WAGES PREMIUM
---------- ----- ---------- ----------
1 A 15000 150
2 A 10000 100
3 B 10000 50
N.B。我在这里假设ID是主键(或者至少,它在整个表中是唯一的!)。
答案 2 :(得分:0)
尝试;
with data(class, sum_pre, sum_wage) as (
select class, sum(Premium), sum(Wages)
from tbl
group by class
)
select t.ID, t.class
t.Wages * s.sum_pre/ s.sum_wage as val
from tbl t
join data s on s.class = t.class
更新
MERGE
INTO tbl t
USING (
with data(class, sum_pre, sum_wage) as (
select class, sum(Premium), sum(Wages)
from tbl
group by class
)
select t.ID
t.Wages * s.sum_pre/ s.sum_wage as val
from tbl t
join data s on s.class = t.class
) x
ON (x.ID = t.ID)
WHEN MATCHED THEN
UPDATE
SET premium = x.val;