如何计算PL / SQL中的分数计算?

时间:2015-10-01 12:59:12

标签: sql oracle plsql

我想在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 ......

我可以补充一点,我必须做一个更新声明......

请你能帮帮我吗?

非常感谢

3 个答案:

答案 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;