1、 债项评级统计报表
CREATE OR REPLACE PROCEDURE SP_DEBT_RATING_RESULT_QUERY( P_RATING_TIME VARCHAR2, P_ORGSEQ VARCHAR2, P_SMALL_CORP_LOAN_CD VARCHAR2, P_CUR OUT IRS_REF.T_CURSOR) AS V_ORGSEQ VARCHAR2(12) := NVL(P_ORGSEQ,'99999'); V_SMALL_CORP_LOAN_CD VARCHAR2(12) := NVL(P_SMALL_CORP_LOAN_CD,'!'); BEGIN /***********************************************************************/ /***********构造新的客户信息表******************************************/ /***********************************************************************/ --取出客户表中最新的记录 INSERT INTO T_CUSTOMER_NEWEST SELECT A.POINT_CMIS_ID FROM CUSTOMER A WHERE A.CUST_STATUS='1' AND (POINT_CMIS_ID, CREATE_TIME) IN (SELECT B.POINT_CMIS_ID, MAX(B.CREATE_TIME) FROM CUSTOMER B GROUP BY B.POINT_CMIS_ID); --取出贷款合同表中,状态为已发放的合同信息 (控制条件:经办机构、小企业标志) INSERT INTO T_LOAN_CONTRACT SELECT A.CUST_ID, V_ORGSEQ, A.SMALL_CORP_LOAN_CD, A.CONTRACT_CODE FROM LOAN_CONTRACT A INNER JOIN OM_ORGANIZATION B ON A.OPERATE_DEPT_NO = B.ORGCODE WHERE A.LOAN_CONTRACT_STATUS = '21002' AND B.ORGSEQ LIKE V_ORGSEQ||'%' AND A.SMALL_CORP_LOAN_CD IN (DECODE(V_SMALL_CORP_LOAN_CD,'1','1'),DECODE(V_SMALL_CORP_LOAN_CD,'2','2'),DECODE(V_SMALL_CORP_LOAN_CD,'2','3'),DECODE(V_SMALL_CORP_LOAN_CD,'2','4'),DECODE(V_SMALL_CORP_LOAN_CD,'!','1'),DECODE(V_SMALL_CORP_LOAN_CD,'!','2'),DECODE(V_SMALL_CORP_LOAN_CD,'!','3'),DECODE(V_SMALL_CORP_LOAN_CD,'!','4')); --进行过客户评级的客户信息 INSERT INTO T_KH_INFO SELECT A.POINT_CMIS_ID, V_ORGSEQ, B.SMALL_CORP_LOAN_CD,B.CONTRACT_CODE FROM T_CUSTOMER_NEWEST A INNER JOIN T_LOAN_CONTRACT B ON A.POINT_CMIS_ID = B.CUST_ID; --根据客户ID取出经办机构、认证机构信息 /***********************************************************************/ /***********算出每个级别笔数/所有级别总笔数 ************************/ /***********************************************************************/ INSERT INTO T_ZBL_DEBT SELECT A1.RATING_TIME,A1.LGD_LEVEL,BS,BS/ZBS ZBL FROM ( SELECT A.RATING_TIME, A.LGD_LEVEL, COUNT(*) BS FROM DEBT_RATING_RESULT_HISTORY A INNER JOIN T_KH_INFO B ON A.CUST_ID=B.POINT_CMIS_ID --AND A.LOAN_CONTRACT_ID=B.CONTRACT_CODE WHERE A.RATING_TIME = TO_DATE(P_RATING_TIME,'YYYYMMDD') --传入条件:评级时间 GROUP BY A.RATING_TIME, A.LGD_LEVEL) A1 --取分类结果表每个级别的笔数 LEFT JOIN (SELECT A.RATING_TIME, COUNT(*) ZBS FROM DEBT_RATING_RESULT_HISTORY A INNER JOIN T_KH_INFO B ON A.CUST_ID=B.POINT_CMIS_ID --AND A.LOAN_CONTRACT_ID=B.CONTRACT_CODE WHERE A.RATING_TIME = TO_DATE(P_RATING_TIME,'YYYYMMDD') --传入条件:评级时间 GROUP BY A.RATING_TIME) A2 --取分类结果表所有级别的总笔数 ON A1.RATING_TIME = A2.RATING_TIME ORDER BY A1.LGD_LEVEL; /***********************************************************************/ /***********算出每个级别的合同余额/所有合同的总余额 ***********/ /***********************************************************************/ INSERT INTO T_ZBY_DEBT SELECT A1.RATING_TIME,A1.LGD_LEVEL,A1.SXYE,A1.SXYE / NVL(A2.ZSXYE,0) ZBY --ALTER BY NISJ 测试用 FROM (SELECT A.RATING_TIME,A.LGD_LEVEL,SUM(NVL(B.CORPUS_AMOUNT, 0) + NVL(B.OVERDUE_IN, 0) + NVL(B.OVERDUE_OUT, 0)) SXYE FROM DEBT_RATING_RESULT_HISTORY A --算出分类结果表中每个级别的合同余额 LEFT JOIN DUE_BILL B ON A.LOAN_CONTRACT_ID = B.LOAN_CONTRACT_ID INNER JOIN T_KH_INFO C ON A.CUST_ID = C.POINT_CMIS_ID --AND A.LOAN_CONTRACT_ID=C.CONTRACT_CODE WHERE A.RATING_TIME = TO_DATE(P_RATING_TIME,'YYYYMMDD') GROUP BY A.RATING_TIME,A.LGD_LEVEL) A1 LEFT JOIN (SELECT A.RATING_TIME,SUM(NVL(B.CORPUS_AMOUNT, 0) + NVL(B.OVERDUE_IN, 0) + NVL(B.OVERDUE_OUT, 0)) ZSXYE FROM DEBT_RATING_RESULT_HISTORY A --算出分类结果表中所有级别的合同余额 LEFT JOIN DUE_BILL B ON A.LOAN_CONTRACT_ID = B.LOAN_CONTRACT_ID INNER JOIN T_KH_INFO C ON A.CUST_ID = C.POINT_CMIS_ID --AND A.LOAN_CONTRACT_ID=C.CONTRACT_CODE WHERE A.RATING_TIME = TO_DATE(P_RATING_TIME,'YYYYMMDD') GROUP BY A.RATING_TIME) A2 ON A1.RATING_TIME = A2.RATING_TIME ORDER BY A1.LGD_LEVEL; /***********************************************************************/ /***********债项评级结果插入到T_DEBT_RATING_RESULT_QUERY临时表**********/ /***********************************************************************/ INSERT INTO T_DEBT_RATING_RESULT_QUERY SELECT X.RATING_TIME, X.LGD_LEVEL, X.BS, DECODE(SUBSTR(ROUND(TO_NUMBER(X.ZBL*100),2)||'%',1,1),'.','0'||ROUND(TO_NUMBER(X.ZBL*100),2)||'%',ROUND(TO_NUMBER(X.ZBL*100),2)||'%') CUSTSCALE, Y.SXYE, DECODE(SUBSTR(ROUND(TO_NUMBER(Y.ZBY*100),2)||'%',1,1),'.','0'||ROUND(TO_NUMBER(Y.ZBY*100),2)||'%',ROUND(TO_NUMBER(Y.ZBY*100),2)||'%') REMIANSCALE, V_ORGSEQ, V_SMALL_CORP_LOAN_CD FROM T_ZBL_DEBT X --算出每个级别笔数/所有级别总笔数 INNER JOIN T_ZBY_DEBT Y --算出每个级别的合同余额/所有合同的总余额 ON X.RATING_TIME = Y.RATING_TIME AND X.LGD_LEVEL = Y.LGD_LEVEL --两个结果按评级结果级别联在一起 WHERE X.RATING_TIME = TO_DATE(P_RATING_TIME, 'YYYY-MM-DD') ; /***********************************************************************/ /************************打开分页游标 *********************/ /***********************************************************************/ OPEN P_CUR FOR SELECT RATING_TIME, LGD_LEVEL, BS, CUSTSCALE, SXYE, REMIANSCALE, OPERATE_DEPT_NO, SMALL_CORP_LOAN_CD FROM T_DEBT_RATING_RESULT_QUERY UNION ALL SELECT MAX(A.RATING_TIME),NULL,SUM(A.BS),'100%',SUM(A.SXYE),'100%',MAX(A.OPERATE_DEPT_NO),MAX(A.SMALL_CORP_LOAN_CD) FROM T_DEBT_RATING_RESULT_QUERY A; END; /
2、 客户评级统计报表
CREATE OR REPLACE PROCEDURE SP_CUST_RATING_RESULT_QUERY( P_RATING_TIME VARCHAR2, P_ORGSEQ VARCHAR2, P_ORG_APPROVAL VARCHAR2, P_CUR OUT IRS_REF.T_CURSOR) AS V_ORGSEQ VARCHAR2(12) := NVL(P_ORGSEQ,'99999'); V_ORG_APPROVAL VARCHAR2(12) := NVL(P_ORG_APPROVAL,'!'); BEGIN /***********************************************************************/ /***********构造最新评级的、有效的统计的客户评级结果信息 *********/ /***********************************************************************/ INSERT INTO T_CUST_RATING_RESULT_NEWEST_C SELECT A.ORG_APPROVAL, A.CUST_CUSTID,A.CONFIRM_TIME,A.FINAL_RATING FROM CUST_RATING_RESULT A WHERE A.ORG_APPROVAL IN (DECODE(V_ORG_APPROVAL,'1','1'),DECODE(V_ORG_APPROVAL,'2','2'),DECODE(V_ORG_APPROVAL,'!','1'),DECODE(V_ORG_APPROVAL,'!','2')) AND A.CONFIRM_TIME <= TO_DATE(P_RATING_TIME , 'YYYYMMDD') AND (CUST_CUSTID, CONFIRM_TIME) IN (SELECT A.CUST_CUSTID, MAX(A.CONFIRM_TIME) FROM CUST_RATING_RESULT A WHERE A.RATING_STATUS = '5' AND A.CONFIRM_TIME IS NOT NULL AND A.FINAL_RATING IS NOT NULL GROUP BY A.CUST_CUSTID); /***********************************************************************/ /***********构造最新的、已经进行过客户评级过的客户信息表******************************************/ /***********************************************************************/ --生成最新的客户临时表 INSERT INTO T_CUSTOMER_NEWEST_C SELECT B.ORGSEQ, A.POINT_CMIS_ID FROM CUSTOMER A INNER JOIN OM_ORGANIZATION B ON A.JBJG_NO=B.ORGCODE WHERE A.CUST_STATUS='1' AND B.ORGSEQ LIKE V_ORGSEQ||'%' AND (A.POINT_CMIS_ID, A.CREATE_TIME) IN (SELECT B.POINT_CMIS_ID, MAX(B.CREATE_TIME) FROM CUSTOMER B GROUP BY B.POINT_CMIS_ID); --生成新的、已经进行过客户评级过的客户信息表 INSERT INTO T_KH_INFO_C SELECT A.POINT_CMIS_ID, A.ORGSEQ, B.ORG_APPROVAL FROM T_CUSTOMER_NEWEST_C A --客户表中最新的记录 INNER JOIN T_CUST_RATING_RESULT_NEWEST_C B --分类结果表中,最新的分类结果信息 ON A.POINT_CMIS_ID = B.CUST_CUSTID; --根据客户ID取出经办机构、认证机构信息 /***********************************************************************/ /***********算出每个级别笔数/所有级别总笔数 ************************/ /***********************************************************************/ --1、算出已经评级和未评级的每个级别的个数 INSERT INTO T_ZBL_CUST(CONFIRM_TIME, ORGSEQ, ORG_APPROVAL, FINAL_RATING, BS, ZBL) SELECT TO_TIMESTAMP(P_RATING_TIME,'YYYY-MM-DD'), V_ORGSEQ, V_ORG_APPROVAL, B.FINAL_RATING, COUNT(*) BS, NULL FROM T_KH_INFO_C A LEFT JOIN T_CUST_RATING_RESULT_NEWEST_C B ON A.POINT_CMIS_ID = B.CUST_CUSTID GROUP BY A.ORG_APPROVAL, B.FINAL_RATING UNION ALL SELECT TO_TIMESTAMP(P_RATING_TIME,'YYYY-MM-DD'), V_ORGSEQ, V_ORG_APPROVAL, 'WPJ', COUNT(*) BS, NULL FROM T_CUSTOMER_NEWEST_C A LEFT JOIN T_CUST_RATING_RESULT_NEWEST_C B ON A.POINT_CMIS_ID = B.CUST_CUSTID WHERE B.CUST_CUSTID IS NULL; --2、插入每个级别(包括未评级)占总数的比例 INSERT INTO T_ZBL_CUST(CONFIRM_TIME, ORGSEQ, ORG_APPROVAL, FINAL_RATING, BS, ZBL) SELECT A.CONFIRM_TIME, A.ORGSEQ, A.ORG_APPROVAL, A.FINAL_RATING,A.BS, A.BS / B.ZBS FROM T_ZBL_CUST A LEFT JOIN (SELECT A1.CONFIRM_TIME, A1.ORGSEQ, A1.ORG_APPROVAL, SUM(A1.BS) ZBS FROM T_ZBL_CUST A1 GROUP BY A1.CONFIRM_TIME, A1.ORGSEQ, A1.ORG_APPROVAL) B ON A.CONFIRM_TIME = B.CONFIRM_TIME AND A.ORGSEQ = B.ORGSEQ AND A.ORG_APPROVAL = B.ORG_APPROVAL; --3、删除比例为空的信息 DELETE T_ZBL_CUST WHERE ZBL IS NULL; /***********************************************************************/ /***********算出每个级别的合同余额/所有合同的总余额 ***********/ /***********************************************************************/ --1、算出已经评级和未评级的每个级别的合同余额 INSERT INTO T_ZBY_CUST(CONFIRM_TIME, ORGSEQ, ORG_APPROVAL, FINAL_RATING, SXYE, ZBY) SELECT TO_TIMESTAMP(P_RATING_TIME,'YYYY-MM-DD'), V_ORGSEQ, V_ORG_APPROVAL,B.FINAL_RATING,SUM(NVL(D.CORPUS_AMOUNT, 0) + NVL(D.OVERDUE_IN, 0) + NVL(D.OVERDUE_OUT, 0)) SXYE,NULL FROM T_KH_INFO_C A LEFT JOIN T_CUST_RATING_RESULT_NEWEST_C B --算出分类结果表中每个级别的合同余额 ON A.POINT_CMIS_ID = B.CUST_CUSTID LEFT JOIN LOAN_CONTRACT C ON A.POINT_CMIS_ID = C.CUST_ID LEFT JOIN DUE_BILL D ON C.CONTRACT_CODE = D.LOAN_CONTRACT_ID GROUP BY B.FINAL_RATING UNION ALL SELECT TO_TIMESTAMP(P_RATING_TIME,'YYYY-MM-DD'), V_ORGSEQ, V_ORG_APPROVAL, 'WPJ', SUM(NVL(D.CORPUS_AMOUNT, 0) + NVL(D.OVERDUE_IN, 0) + NVL(D.OVERDUE_OUT, 0)) SXYE, NULL FROM T_CUSTOMER_NEWEST_C A LEFT JOIN T_CUST_RATING_RESULT_NEWEST_C B ON A.POINT_CMIS_ID = B.CUST_CUSTID LEFT JOIN LOAN_CONTRACT C ON A.POINT_CMIS_ID=C.CUST_ID LEFT JOIN DUE_BILL D ON C.CONTRACT_CODE = D.LOAN_CONTRACT_ID WHERE B.CUST_CUSTID IS NULL; --2、插入每个级别(包括未评级)占总合同余额的比例 INSERT INTO T_ZBY_CUST(CONFIRM_TIME, ORGSEQ, ORG_APPROVAL, FINAL_RATING, SXYE, ZBY) SELECT A.CONFIRM_TIME, A.ORGSEQ, A.ORG_APPROVAL, A.FINAL_RATING,A.SXYE, A.SXYE / B.ZSXYE FROM T_ZBY_CUST A LEFT JOIN (SELECT A1.CONFIRM_TIME, A1.ORGSEQ, A1.ORG_APPROVAL, SUM(A1.SXYE) ZSXYE FROM T_ZBY_CUST A1 GROUP BY A1.CONFIRM_TIME, A1.ORGSEQ, A1.ORG_APPROVAL) B ON A.CONFIRM_TIME = B.CONFIRM_TIME AND A.ORGSEQ = B.ORGSEQ AND A.ORG_APPROVAL = B.ORG_APPROVAL; --3、删除比例为空的信息 DELETE T_ZBY_CUST WHERE ZBY IS NULL; /***********************************************************************/ /***********债项评级结果插入到T_CUST_RATING_RESULT_QUERY临时表**********/ /***********************************************************************/ INSERT INTO T_CUST_RATING_RESULT_QUERY SELECT X.CONFIRM_TIME, X.FINAL_RATING, X.BS, DECODE(SUBSTR(ROUND(TO_NUMBER(X.ZBL*100),2)||'%',1,1),'.','0'||ROUND(TO_NUMBER(X.ZBL*100),2)||'%',ROUND(TO_NUMBER(X.ZBL*100),2)||'%') CUSTSCALE, Y.SXYE, DECODE(SUBSTR(ROUND(TO_NUMBER(Y.ZBY*100),2)||'%',1,1),'.','0'||ROUND(TO_NUMBER(Y.ZBY*100),2)||'%',ROUND(TO_NUMBER(Y.ZBY*100),2)||'%') REMIANSCALE, V_ORGSEQ, V_ORG_APPROVAL FROM T_ZBL_CUST X --算出每个级别笔数/所有级别总笔数 LEFT JOIN T_ZBY_CUST Y --算出每个级别的合同余额/所有合同的总余额 ON X.CONFIRM_TIME = Y.CONFIRM_TIME AND X.FINAL_RATING = Y.FINAL_RATING AND X.ORGSEQ=Y.ORGSEQ AND X.ORG_APPROVAL=Y.ORG_APPROVAL --两个结果按评级结果级别联在一起 WHERE X.CONFIRM_TIME = TO_TIMESTAMP(P_RATING_TIME,'YYYY-MM-DD'); /***********************************************************************/ /************************打开分页游标 *********************/ /***********************************************************************/ OPEN P_CUR FOR SELECT CONFIRM_TIME, FINAL_RATING, BS, CUSTSCALE, SXYE, REMIANSCALE, ORGSEQ, ORG_APPROVAL FROM T_CUST_RATING_RESULT_QUERY UNION ALL SELECT MAX(CONFIRM_TIME), NULL, SUM(BS), '100%', SUM(SXYE), '100%', V_ORGSEQ, V_ORG_APPROVAL FROM T_CUST_RATING_RESULT_QUERY; END; /
3、 总结说明
用到的知识点:
(1)、临时表
create global temporary table
优点:速度快,效率高,代码易于理解
(2)、计算最新的一条记录
AND (A.POINT_CMIS_ID, A.CREATE_TIME) IN (SELECT B.POINT_CMIS_ID, MAX(B.CREATE_TIME) FROM CUSTOMER B GROUP BY B.POINT_CMIS_ID);
(3)、用DECODE实现一对多
AND A.SMALL_CORP_LOAN_CD IN (DECODE(V_SMALL_CORP_LOAN_CD,'1','1'),DECODE(V_SMALL_CORP_LOAN_CD,'2','2'),DECODE(V_SMALL_CORP_LOAN_CD,'2','3'),DECODE(V_SMALL_CORP_LOAN_CD,'2','4'),DECODE(V_SMALL_CORP_LOAN_CD,'!','1'),DECODE(V_SMALL_CORP_LOAN_CD,'!','2'),DECODE(V_SMALL_CORP_LOAN_CD,'!','3'),DECODE(V_SMALL_CORP_LOAN_CD,'!','4')); 表示:V_SMALL_CORP_LOAN_CD是1时取1;是2时取2、3、4;是!时取所有(1、2、3、4)
(4)、ROUND取小数位数
ROUND(TO_NUMBER(X.ZBL*100),2)
(5)、UNION ALL
当计算每一级别的个数与所有级别总和且放在同一结果集中时用到。
SELECT CONFIRM_TIME, FINAL_RATING, BS, CUSTSCALE, SXYE, REMIANSCALE, ORGSEQ, ORG_APPROVAL FROM T_CUST_RATING_RESULT_QUERY UNION ALL SELECT MAX(CONFIRM_TIME), NULL, SUM(BS), '100%', SUM(SXYE), '100%', V_ORGSEQ, V_ORG_APPROVAL FROM T_CUST_RATING_RESULT_QUERY;
(6)、REF游标
(7)、更新的理解
可以先删除再插入,也可以先插入再删除,不用update,也是更新。
(8)、百分比
数字*100转成字符串,再||‘%’
(9)、变量默认值的使用
V_ORGSEQ VARCHAR2(12) := NVL(P_ORGSEQ,'99999'); V_ORG_APPROVAL VARCHAR2(12) := NVL(P_ORG_APPROVAL,'!');
(10)、工整的版书、详尽的注释