子代的递归SUM以计算oracle 12c中的另一个字段

时间:2019-07-09 14:32:12

标签: sql oracle

我有一个问题要计算父母的孩子总数,而父母是另一个父母的孩子。

我尝试使用CTE递归来实现,但是我坚持了。

  create table table1 (ROWNRA varchar(10) ,
           CONTRACT_NO_A  varchar(100),
           START_DATE_A date,
           END_DATE_A date ,
           RISK_AMOUNT_A number (10,2)
           );
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values  ('1','CON1',to_date('2017/04/06','YYYY/MM/DD'),to_date('2017/05/05','YYYY/MM/DD'),278000);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('2','CON2',to_date('2017/05/02','YYYY/MM/DD'),to_date('2017/06/01','YYYY/MM/DD'),123570.7);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('3','CON3',to_date('2017/05/02','YYYY/MM/DD'),to_date('2017/06/01','YYYY/MM/DD'),147664.12);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('4','CON4',to_date('2017/05/02','YYYY/MM/DD'),to_date('2017/06/01','YYYY/MM/DD'),183859.92);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('5','CON1',to_date('2017/05/06','YYYY/MM/DD'),to_date('2017/06/05','YYYY/MM/DD'),278000);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('6','CON2',to_date('2017/06/02','YYYY/MM/DD'),to_date('2017/07/01','YYYY/MM/DD'),123570.7);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('7','CON3',to_date('2017/06/02','YYYY/MM/DD'),to_date('2017/07/01','YYYY/MM/DD'),147664.12);
Insert into table1 (ROWNRA,CONTRACT_NO_A,START_DATE_A,END_DATE_A,RISK_AMOUNT_A) values ('8','CON4',to_date('2017/06/02','YYYY/MM/DD'),to_date('2017/07/01','YYYY/MM/DD'),183859.92);

我的代码:

with cte (rownra, contract_no_A, start_date_A, end_date_A,  risk_amount_A, lvl,  rownrB, risk_cumul)
    as (select rownra, contract_no_A, start_date_A, end_date_A,  risk_amount_A, 0 as lvl, rownra as rownrb, risk_amount_A as  risk_cumul
        from table1

        UNION ALL

        SELECT PAR.rownra, CTE.contract_no_A, par.start_date_A, par.end_date_A,  cte.risk_amount_A , CTE.lvl +1 AS LVL, cte.ROWNRB,
                par.risk_amount_A + CTE.risk_cumul
             -- cte.risk_cumul 
        FROM table1 PAR, CTE CTE
        WHERE  PAR.rownra > CTE.rownra
                      and PAR.start_date_A <= CTE.end_date_A-- (+) 
        AND CTE.LVL=0
        )


  ,t2 as ( select * from (
    select rownra, contract_no_A, start_date_A, end_date_A,  sum(risk_amount_A) over (partition by rownra) cumulativa_RA, rownrb ,
    case when sum(risk_amount_A) over (partition by rownra)*0.9-500000<0 then 0
                else 
              sum(risk_amount_A) over (partition by rownra)*0.9-500000
                end reinsured
    from cte)
    where rownra=rownrb)

,cte2 (ROWNRA,  CONTRACT_NO_A,  START_DATE_A,   END_DATE_A,  CUMULATIVA_RA,     ROWNRB, REINSURED,LVL)
as (select ROWNRA,  CONTRACT_NO_A,  START_DATE_A,   END_DATE_A,  CUMULATIVA_RA,     ROWNRB, REINSURED, 0 AS LVL
      from t2
      union ALL

      SELECT T_2.ROWNRA,    CTE_2.CONTRACT_NO_A,    T_2.START_DATE_A,   T_2.END_DATE_A,  T_2.CUMULATIVA_RA,     CTE_2.ROWNRB,   T_2.REINSURED, CTE_2.LVL+1

      FROM T2 T_2, CTE2 CTE_2
      WHERE T_2.rownra > CTE_2.rownra
                      and T_2.start_date_A <= CTE_2.end_date_A
                         AND CTE_2.LVL=0
)
SELECT * FROM CTE2
ORDER BY ROWNRA, LVL

我的结果(不需要)

ROWNRA|CONTRACT_NO_A|START_DATE_A|END_DATE_A|RISK_AMOUNT_A|LVL|ROWNRB|RISK_CUMUL
ROWNRA|CONTRACT_NO_A|START_DATE_A|END_DATE_A|CUMULATIVA_RA|ROWNRB|REINSURED|LVL
1|CON1|2017/04/06|2017/05/05|278000|1|0|0
2|CON2|2017/05/02|2017/06/01|401570,7|2|0|0
2|CON1|2017/05/02|2017/06/01|401570,7|1|0|1
3|CON3|2017/05/02|2017/06/01|549234,82|3|0|0
3|CON2|2017/05/02|2017/06/01|549234,82|2|0|1
3|CON1|2017/05/02|2017/06/01|549234,82|1|0|1
4|CON4|2017/05/02|2017/06/01|733094,74|4|159785,266|0
4|CON1|2017/05/02|2017/06/01|733094,74|1|159785,266|1
4|CON3|2017/05/02|2017/06/01|733094,74|3|159785,266|1
4|CON2|2017/05/02|2017/06/01|733094,74|2|159785,266|1
5|CON1|2017/05/06|2017/06/05|733094,74|5|159785,266|0
5|CON4|2017/05/06|2017/06/05|733094,74|4|159785,266|1
5|CON3|2017/05/06|2017/06/05|733094,74|3|159785,266|1
5|CON2|2017/05/06|2017/06/05|733094,74|2|159785,266|1
6|CON2|2017/06/02|2017/07/01|401570,7|6|0|0
6|CON1|2017/06/02|2017/07/01|401570,7|5|0|1
7|CON3|2017/06/02|2017/07/01|549234,82|7|0|0
7|CON1|2017/06/02|2017/07/01|549234,82|5|0|1
7|CON2|2017/06/02|2017/07/01|549234,82|6|0|1
8|CON4|2017/06/02|2017/07/01|733094,74|8|159785,266|0
8|CON2|2017/06/02|2017/07/01|733094,74|6|159785,266|1
8|CON1|2017/06/02|2017/07/01|733094,74|5|159785,266|1
8|CON3|2017/06/02|2017/07/01|733094,74|7|159785,266|1

所需结果:

ROWNRA|CONTRACT_NO_A|START_DATE_A|END_DATE_A|CUMULATIVA_RA |ROWNRB|REINSURED|LVL
1|CON1|2017-04-06|2017-05-05|278 000,00    |1|0|0
2|CON2|2017-05-02|2017-06-01|401 570,70    |2|0|0
3|CON3|2017-05-02|2017-06-01|549 234,82    |3|0|0
4|CON4|2017-05-02|2017-06-01|733 094,74    |4|159785,266|0
5|CON1|2017-05-06|2017-06-05|573 309,47    |5|0|0
6|CON2|2017-06-02|2017-07-01|401 570,70    |6|0|0
7|CON3|2017-06-02|2017-07-01|549 234,82    |7|0|0
8|CON4|2017-06-02|2017-07-01|733 094,74    |8|159785,266|0

目标是计算包括父母在内的所有子代的risk_amount的总和,即con4将为con4 + con3 + con2 + con1(因为它们在一起至少持续1天),然后该总和乘以0.9并减去500000。如果此计算的结果> 0,则对于父con5(具有子con4),必须在父con5的计算总和中扣除-> con5 = con5 + con4-

0 个答案:

没有答案