我有一个问题要计算父母的孩子总数,而父母是另一个父母的孩子。
我尝试使用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-