数据查询语言优化实例-20210104
最近的实际工作中要参与一些数据汇总工作,因为工作内容不是特别的系统,写的代码也不准备留给谁,所以一开始并没有特别注重执行效率,只要执行不超过5分钟的并没有特别在意。
但工作能让你这么舒服吗,显然不可能。还是遇到了下面必须要盘(优化)的代码。
一 需要优化的语句
-- 执行效率:40分钟以上没有执行完
create table test_table as
select
'20210101' as STAT_DT
,a1.CUST_ID as CUST_ID
,a1.USER_LOAN_FLG as USER_LOAN_FLG
,a1.SQ_LOAN_FLG as SQ_LOAN_FLG
,a1.CURR_SQ_LOAN_FLG as CURR_SQ_LOAN_FLG
,(case when a7.CIF_NO is not null then 1 else 0 end) as BLK_FLG
,'0' as EMP_FLG
,a1.EC_LOAN_FLG as EC_LOAN_FLG
,a1.BAD_LOAN_FLG as BAD_LOAN_FLG
,'0' as OD_LOAN_FLG
,a2.AGE_CD as AGE_CD
,a2.SEX_CD as SEX_CD
,a2.DEPO_OPEN_DUR as DEPO_OPEN_DUR
,a2.CROSS_ORG_CNT as CROSS_ORG_CNT
,a2.DEPO_ACCT_CNT as DEPO_ACCT_CNT
,a2.CURR_BAL as DEPO_BAL
,a2.LOAN_BAL as LOAN_BAL
,a2.CURR_BAL/a2.LOAN_BAL as DEPO_LOAN_RT
,a4.DEPO_BAL_20191130 as DEPO_BAL_20191130
,a5.M_AVG_DEPO_BAL as M_AVG_DEPO_BAL
,a6.MAX_M_AVG_DEPO_BAL as MAX_M_AVG_DEPO_BAL
,a6.MAX_M_AVG_DEPO_BAL_MCNT as MAX_M_AVG_DEPO_BAL_MCNT
,(case when a10.CUST_ID is null then 1 else 0 end) as CARD_FLG
,a1.LOAN_H_CNT as LOAN_H_CNT
,(case when a8.master_cust_no is null then 0 else 1 end) as TIME_FLG
,a9.M12_TRAN_AMT as M12_TRAN_AMT
,a9.M12_TRAN_CNT as M12_TRAN_CNT
,a9.M12_D_TRAN_AMT as M12_D_TRAN_AMT
,a9.M12_C_TRAN_AMT as M12_C_TRAN_AMT
,a9.M12_MAX_SIGLE_TRAN_AMT as M12_MAX_SIGLE_TRAN_AMT
,a9.M12_D_MAX_SIGLE_TRAN_AMT as M12_D_MAX_SIGLE_TRAN_AMT
,a9.M12_C_MAX_SIGLE_TRAN_AMT as M12_C_MAX_SIGLE_TRAN_AMT
,(a2.CURR_BAL-a4.DEPO_BAL_20191130)/M12_C_TRAN_AMT as RETEN_RT
,'0' as Y1
,'0' as Y2
,(case when a1.LOAN_H_CNT>1 and a2.LOAN_BAL>0 then 1 else 0 end) as Y3
from (
select
b1.CIF_ID as CUST_ID
,(CASE WHEN SUM(CASE WHEN b1.BEG_DATE BETWEEN 20171201 AND 20201130 THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) as USER_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.FIN_DATE BETWEEN 20191201 AND 20201130 THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) as SQ_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.DUE_STS='9' THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) as CURR_SQ_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.PRDT_NO IN ('C107','C118','C119','C120','C127','129','C130','C108','C112') THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) AS EC_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.FIVE_STS IN ('3','4','5') THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) AS BAD_LOAN_FLG
,SUM(CASE WHEN b1.BEG_DATE BETWEEN 20171201 AND 20201130 THEN 1 ELSE 0 END) AS LOAN_H_CNT
from F_CMS_RPT_XD b1
where CIF_ID like '010%'--个人客户
group by b1.CIF_ID
) a1
LEFT JOIN ANA_STRUCTURAL a2
ON a1.CUST_ID = a2.CUST_ID
-- LEFT JOIN
-- (
-- select CUST_NO as CUST_NO,sum(DUEBILL_BAL) as LOAN_BAL
-- from F_LN_LN_DUE_RECORD
-- where CUST_NO like '01%' and record_dt = '20201130'-- 取对私客户
-- group by CUST_NO
-- ) a3 --借据月表
-- ON a1.CUST_ID = a3.CUST_NO
LEFT JOIN
(
select master_cust_no,sum(PRT_LED_BAL) as DEPO_BAL_20191130
from ADPXX_CQ_RECORD
where record_dt = '20191130'
group by master_cust_no
) a4 --存款账户月表
ON a1.CUST_ID = a4.master_cust_no
LEFT JOIN
(
select master_cust_no,sum(AVGBAL) as M_AVG_DEPO_BAL
from ADPXX_AVG_ACCTNO
where ym = '202011'
group by master_cust_no
) a5 --历史月日均记录
ON a1.CUST_ID = a5.master_cust_no
LEFT JOIN
(
select
master_cust_no,AVG_MONTH as MAX_M_AVG_DEPO_BAL,
months_between(to_date('202011','yyyymm'),to_date(ym,'yyyymm')) as MAX_M_AVG_DEPO_BAL_MCNT
from ADPXX_MAXAVG_MASTER_CUST_NO
) a6 --最高月日均记录
ON a1.CUST_ID = a6.master_cust_no
LEFT JOIN
(
select distinct CIF_NO
from F_CMS_CIF_BLACK_CAUSE
) a7 --黑名单
ON a1.CUST_ID = a7.CIF_NO
LEFT JOIN
(
select distinct master_cust_no
from ADPXX_CQ_RECORD
where
(record_dt between 20171201 and 20201130) --近三年
and LIAB_PRDT_TYPE = '1'--取定期
group by master_cust_no
) a8 --取定期历史记录
ON a1.CUST_ID = a8.master_cust_no
LEFT JOIN
(
select
b2.MASTER_CUST_NO as CUST_ID
,SUM(b1.TX_AMT) as M12_TRAN_AMT
,count(1) as M12_TRAN_CNT
,SUM(CASE WHEN b1.CR_DR_MAINT_IND = 0 THEN b1.TX_AMT ELSE 0 END) as M12_D_TRAN_AMT
,SUM(CASE WHEN b1.CR_DR_MAINT_IND = 1 THEN b1.TX_AMT ELSE 0 END) as M12_C_TRAN_AMT
,MAX(b1.TX_AMT) as M12_MAX_SIGLE_TRAN_AMT
,MAX(CASE WHEN b1.CR_DR_MAINT_IND = 0 THEN b1.TX_AMT ELSE 0 END) as M12_D_MAX_SIGLE_TRAN_AMT
,MAX(CASE WHEN b1.CR_DR_MAINT_IND = 1 THEN b1.TX_AMT ELSE 0 END) as M12_C_MAX_SIGLE_TRAN_AMT
from F_CI_BDPAL b1
left join ADPXX_CQ b2
on b1.acct_no = b2.acct_no
where
b1.TX_DT BETWEEN 20191201 AND 20201130
and b1.MEMO_CODE NOT IN ('000212','B00102','B00104','B10003') --入息、放贷、还息、还贷
and (b1.RVS_FLG NOT IN ('1','2') OR b1.BRVS_FLG<>'1') --冲正和被冲正
group by b2.MASTER_CUST_NO
) a9 --账户余额发生明细表
ON a1.CUST_ID = a9.CUST_ID
LEFT JOIN
(
select
distinct a2.kehhao as CUST_ID
from F_CCS_CARD a1
left join F_CI_BDSKH a2
on trim(a1.CUSTR_NBR) = trim(a2.ZHJHAO)
where a2.ZHJNZL = '10' and a1.CANCL_DAY <= 20201130 and a1.ISSUE_DAY <= 20201130
) a10
ON a1.CUST_ID = a10.CUST_ID
;
二 语句效率执行慢原因解析 以及 解决方式
- left join 的表太多
说一下left join 的算法
解决方式:
根据业务类别和left join 表数据量的的不同,将代码拆分成几部分。具体的实现方式就是建立中间表(临时表),上述代码我拆分成了两部分,第一部分为客户的基本信息以及一些容易算出的字段指标,第二部分则为数据量庞大的交易明细汇总部分。
- left join 的一些表数据太大
解决方式:
我们这些数据量很大的表,我们可以通过加强where条件筛选出我们需要的数据,也可以直接将数据一次性汇总成我们需要的表。如上述代码中的 a9 表,表数据总数约2亿,我们只提取固定1年时间仍然是很大的数据量,因此可以在此的基础上在增加客户号的筛选条件,以及增加索引。
- 语句中牵扯了大量的聚合函数
解决方式:
在创建中间表的过程中,已经将大部分的聚合函数执行完毕,因此在汇总最后结果时,两张表只需要简单的left join 即可。
- 其它
上述的解决方式都是大方向的优化,在具体的优化还可以补充以下方式:
- 为中间表及需要的表创建索引,创建索引可以解决大部分的查询效率问题;
- 增加临时表空间、分库分表等操作也会增加数据的查询效率,但在本次优化过程中并没有使用,不做讨论。
三 优化后代码
------------------------------------------------------------------------------
-- 1. 客户群主表
------------------------------------------------------------------------------
drop table ana_tmp_t1 ;
create table ana_tmp_t1 as
select
a1.CUST_ID as CUST_ID -- 客户号
,a1.USER_LOAN_FLG as USER_LOAN_FLG -- 是否在20171201-20201130有过用信
,a1.SQ_LOAN_FLG as SQ_LOAN_FLG -- 是否在20191201-20201130结清贷款
,a1.CURR_SQ_LOAN_FLG as CURR_SQ_LOAN_FLG -- 当前是否结清客户
,(case when a7.CIF_NO is not null then 1 else 0 end) as BLK_FLG -- 是否黑名单客户
,a1.EC_LOAN_FLG as EC_LOAN_FLG -- 是否有过按揭贷款、贫困贷、助学贷
,a1.BAD_LOAN_FLG as BAD_LOAN_FLG -- 是否有过五级不良贷款
,a1.LOAN_H_YQDAY_MCNT as LOAN_H_YQDAY_MCNT -- 历史最大逾期天数 -- 76 结清日期都为null
,a11.AGE_CD as AGE_CD -- 年龄
,a11.SEX_CD as SEX_CD -- 性别
,nvl2(a2.DEPO_OPEN_DUR,a2.DEPO_OPEN_DUR,0) as DEPO_OPEN_DUR -- 存款开户时长
,nvl2(a2.CROSS_ORG_CNT,a2.CROSS_ORG_CNT,0) as CROSS_ORG_CNT -- 跨网点数
,nvl2(a2.DEPO_ACCT_CNT,a2.DEPO_ACCT_CNT,0) as DEPO_ACCT_CNT -- 存款账户数
,nvl2(a2.CURR_BAL,a2.CURR_BAL,0) as DEPO_BAL -- 当前时点存款余额
,a1.LOAN_BAL as LOAN_BAL -- 当前贷款余额
,(case when a1.LOAN_BAL = 0 then -1 else nvl2(a2.CURR_BAL,a2.CURR_BAL,0)/a1.LOAN_BAL end ) as DEPO_LOAN_RT -- 当前存贷比
,nvl2(a4.DEPO_BAL_20191130,a4.DEPO_BAL_20191130,0) as DEPO_BAL_20191130 -- 20191130时点余额
,nvl2(a5.M_AVG_DEPO_BAL,a5.M_AVG_DEPO_BAL,0) as M_AVG_DEPO_BAL -- 当前月日均存款
,nvl2(a6.MAX_M_AVG_DEPO_BAL,a6.MAX_M_AVG_DEPO_BAL,0) as MAX_M_AVG_DEPO_BAL -- 历史最高月日均存款
,nvl2(a6.MAX_M_AVG_DEPO_BAL_MCNT,a6.MAX_M_AVG_DEPO_BAL_MCNT,0) as MAX_M_AVG_DEPO_BAL_MCNT -- 历史最高月日均存款距当前月份
,(case when a10.CUST_ID is null then 1 else 0 end) as CARD_FLG -- 是否有信用卡产品
,a1.LOAN_H_CNT as LOAN_H_CNT -- 近3年贷款次数
,a1.BAD_DUE_FLG as BAD_DUE_FLG -- 是否有过借据不正常的借据
from
(
select
b1.cif_no as CUST_ID
,(CASE WHEN SUM(CASE WHEN b1.BEG_DATE BETWEEN 20171201 AND 20201130 THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) as USER_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.due_sts='9' THEN 0 ELSE 1 END)=0 AND MAX(b1.FIN_DATE) >= 20191201 THEN 1 ELSE 0 END) as SQ_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.due_sts='9' THEN 0 ELSE 1 END)=0 THEN 1 ELSE 0 END) as CURR_SQ_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.PRDT_NO IN ('C107','C118','C119','C120','C127','129','C130','C108','C112','G101','G104','I103') THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) AS EC_LOAN_FLG
,(CASE WHEN SUM(CASE WHEN b1.FIVE_STS IN ('3','4','5') THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) AS BAD_LOAN_FLG
,SUM(CASE WHEN b1.BEG_DATE BETWEEN 20171201 AND 20201130 THEN 1 ELSE 0 END) AS LOAN_H_CNT
,(CASE WHEN SUM(CASE WHEN b1.due_sts not in ('1','9') THEN 1 ELSE 0 END)>0 THEN 1 ELSE 0 END) AS BAD_DUE_FLG -- 是否有过借据不正常的借据
,MAX(b1.LOAN_H_YQDAY_CNT) AS LOAN_H_YQDAY_MCNT -- 最大逾期天数
,SUM(BAL) as LOAN_BAL -- 当前贷款余额
from
(
SELECT
c1.*
,(
CASE
WHEN c1.due_sts = '1' THEN (to_date('20201130','yyyymmdd') -to_date(c1.EXP_ENDDATE,'yyyymmdd')-1)
WHEN c1.due_sts = '9' THEN (to_date(c1.FIN_DATE,'yyyymmdd')-to_date(c1.EXP_ENDDATE,'yyyymmdd')-1)
ELSE 99999
END
) as LOAN_H_YQDAY_CNT
from F_CMS_RPT_XD c1
where c1.cif_no like '010%'--个人客户
-- and c1.FIN_DATE BETWEEN 20191201 AND 20201130
-- and c1.PRDT_NO not in ('G101','G104','I103') -- 'I103':'公积金'
) b1
group by b1.cif_no
) a1
LEFT JOIN ANA_STRUCTURAL a2
ON a1.CUST_ID = a2.CUST_ID
LEFT JOIN
(
select master_cust_no,sum(PRT_LED_BAL) as DEPO_BAL_20191130
from ADPXX_CQ_RECORD
where record_dt = '20191130'
group by master_cust_no
) a4 --存款账户月表
ON a1.CUST_ID = a4.master_cust_no
LEFT JOIN
(
select master_cust_no,sum(AVGBAL) as M_AVG_DEPO_BAL
from ADPXX_AVG_ACCTNO
where ym = '202011'
group by master_cust_no
) a5 --历史月日均记录
ON a1.CUST_ID = a5.master_cust_no
LEFT JOIN
(
select
master_cust_no,AVG_MONTH as MAX_M_AVG_DEPO_BAL,
months_between(to_date('202011','yyyymm'),to_date(ym,'yyyymm')) as MAX_M_AVG_DEPO_BAL_MCNT
from ADPXX_MAXAVG_MASTER_CUST_NO
) a6 --最高月日均记录
ON a1.CUST_ID = a6.master_cust_no
LEFT JOIN
(
select distinct CIF_NO
from F_CMS_CIF_BLACK_CAUSE
) a7 --黑名单
ON a1.CUST_ID = a7.CIF_NO
LEFT JOIN
(
select
distinct a2.kehhao as CUST_ID
from F_CCS_CARD a1
left join F_CI_BDSKH a2
on trim(a1.CUSTR_NBR) = trim(a2.ZHJHAO)
where a2.ZHJNZL = '10' and a2.kehhao like '010%' and a1.CANCL_DAY <= 20201130 and a1.ISSUE_DAY <= 20201130
) a10
ON a1.CUST_ID = a10.CUST_ID
left join
(
select
c1.cif_no as CUST_ID,c2.id_no
,case
when isidcard_new(c2.id_no) = '1' then
trunc(
months_between(
to_date('20201130','yyyymmdd'),
to_date(
case when length(trim(c2.id_no)) = 18
then SubStr(c2.id_no, 7, 8)
else '19' || SubStr(c2.id_no, 7, 6)
end , 'yyyymmdd'
)
)/12
)
else 999 end
as AGE_CD
,case
when isidcard_new(c2.id_no) = '1'
then (
case
when length(trim(c2.id_no)) = 18 and mod(SubStr(c2.id_no, 17, 1),2) = 1 then '1' --男
when length(trim(c2.id_no)) = 18 and mod(SubStr(c2.id_no, 17, 1),2) = 0 then '2' --女
when length(trim(c2.id_no)) = 15 and mod(SubStr(c2.id_no, 15, 1),2) = 1 then '1' --男
when length(trim(c2.id_no)) = 15 and mod(SubStr(c2.id_no, 15, 1),2) = 0 then '2' --女
else '999'
end
) else '999' end
as SEX_CD
from
(
SELECT
b1.cif_no,max(b1.beg_date) as x
FROM F_CMS_RPT_XD b1
where
CIF_NO like '010%'
group by b1.cif_no
) c1
left join
(
SELECT
b1.cif_no,b1.id_no,max(b1.beg_date) as x
FROM F_CMS_RPT_XD b1
where
CIF_NO like '010%'
group by b1.cif_no,b1.id_no
) c2
on c1.cif_no = c2.cif_no and c1.x = c2.x
) a11 -- 对私客户信息表
on a1.CUST_ID = a11.CUST_ID
;
alter table ana_tmp_t1 add primary key (CUST_ID);
------------------------------------------------------------------------------
-- 2. 账户余额发生明细表-数据汇总
------------------------------------------------------------------------------
drop table ana_tmp_t2;
create table ana_tmp_t2 as
select
b2.MASTER_CUST_NO as CUST_ID
,SUM(b1.TX_AMT) as M12_TRAN_AMT
,count(1) as M12_TRAN_CNT
,SUM(CASE WHEN b1.CR_DR_MAINT_IND = 0 THEN b1.TX_AMT ELSE 0 END) as M12_D_TRAN_AMT
,SUM(CASE WHEN b1.CR_DR_MAINT_IND = 1 THEN b1.TX_AMT ELSE 0 END) as M12_C_TRAN_AMT
,MAX(b1.TX_AMT) as M12_MAX_SIGLE_TRAN_AMT
,MAX(CASE WHEN b1.CR_DR_MAINT_IND = 0 THEN b1.TX_AMT ELSE 0 END) as M12_D_MAX_SIGLE_TRAN_AMT
,MAX(CASE WHEN b1.CR_DR_MAINT_IND = 1 THEN b1.TX_AMT ELSE 0 END) as M12_C_MAX_SIGLE_TRAN_AMT
from F_CI_BDPAL b1
left join ADPXX_CQ b2
on b1.acct_no = b2.acct_no
where
b1.TX_DT BETWEEN 20191201 AND 20201130
AND( MEMO_CODE NOT IN ('000212','B00102','B00104','B10003') OR MEMO_CODE IS NULL) --入息、放贷、还息、还贷
and (b1.RVS_FLG NOT IN ('1','2') OR b1.BRVS_FLG<>'1') --冲正和被冲正
group by b2.MASTER_CUST_NO
;
--alter table ana_tmp_t2 add primary key (CUST_ID);
------------------------------------------------------------------------------
-- 2.1. 账户余额发生明细表-数据汇总
------------------------------------------------------------------------------
drop table ana_tmp_t3;
create table ana_tmp_t3 as
select
b2.MASTER_CUST_NO as CUST_ID
,sum(b1.TX_AMT) as M12_C_ALL_TRAN_AMT
from F_CI_BDPAL b1
left join ADPXX_CQ b2
on b1.acct_no = b2.acct_no
where
b1.TX_DT BETWEEN 20191201 AND 20201130
and (b1.RVS_FLG NOT IN ('1','2') OR b1.BRVS_FLG<>'1') --冲正和被冲正
and b1.CR_DR_MAINT_IND = 1
group by b2.MASTER_CUST_NO
;
------------------------------------------------------------------------------
-- 3. 个人贷款客户汇总表-数据汇总
------------------------------------------------------------------------------
drop table ANA_MARKETING_TMP ;
create table ANA_MARKETING_TMP as
select
'20201130' as STAT_DT -- 统计日期
,a1.CUST_ID as CUST_ID -- 客户号
,a1.USER_LOAN_FLG as USER_LOAN_FLG -- 是否在20171201-20201130有过用信
,a1.SQ_LOAN_FLG as SQ_LOAN_FLG -- 是否在20191201-20201130结清贷款
,a1.CURR_SQ_LOAN_FLG as CURR_SQ_LOAN_FLG -- 当前是否结清客户
,a1.BLK_FLG as BLK_FLG -- 是否黑名单客户
,'0' as EMP_FLG -- 是否本行员工
,a1.EC_LOAN_FLG as EC_LOAN_FLG -- 是否有过按揭贷款、贫困贷、助学贷
,a1.BAD_LOAN_FLG as BAD_LOAN_FLG -- 是否有过五级不良贷款
,a1.LOAN_H_YQDAY_MCNT as LOAN_H_YQDAY_MCNT -- 历史最大逾期天数
,a1.AGE_CD as AGE_CD -- 年龄
,a1.SEX_CD as SEX_CD -- 性别
,a1.DEPO_OPEN_DUR as DEPO_OPEN_DUR -- 存款开户时长
,a1.CROSS_ORG_CNT as CROSS_ORG_CNT -- 跨网点数
,a1.DEPO_ACCT_CNT as DEPO_ACCT_CNT -- 存款账户数
,a1.DEPO_BAL as DEPO_BAL -- 当前时点存款余额
,a1.LOAN_BAL as LOAN_BAL -- 当前贷款余额
,a1.DEPO_LOAN_RT as DEPO_LOAN_RT -- 当前存贷比
,a1.DEPO_BAL_20191130 as DEPO_BAL_20191130 -- 20191130时点余额
,a1.M_AVG_DEPO_BAL as M_AVG_DEPO_BAL -- 当前月日均存款
,a1.MAX_M_AVG_DEPO_BAL as MAX_M_AVG_DEPO_BAL -- 历史最高月日均存款
,a1.MAX_M_AVG_DEPO_BAL_MCNT as MAX_M_AVG_DEPO_BAL_MCNT -- 历史最高月日均存款距当前月份
,a1.CARD_FLG as CARD_FLG -- 是否有信用卡产品
,a1.LOAN_H_CNT as LOAN_H_CNT -- 近3年贷款次数
,(case when a8.master_cust_no is null then 0 else 1 end) as TIME_FLG -- 历史是否有定期产品
,nvl2(a9.M12_TRAN_AMT,a9.M12_TRAN_AMT,0) as M12_TRAN_AMT -- 近一年总交易金额
,nvl2(a9.M12_TRAN_CNT,a9.M12_TRAN_CNT,0) as M12_TRAN_CNT -- 近一年总交易笔数
,nvl2(a9.M12_D_TRAN_AMT,a9.M12_D_TRAN_AMT,0) as M12_D_TRAN_AMT -- 近一年借方总交易金额
,nvl2(a9.M12_C_TRAN_AMT,a9.M12_C_TRAN_AMT,0) as M12_C_TRAN_AMT -- 近一年贷方总交易金额
,nvl2(a9.M12_MAX_SIGLE_TRAN_AMT,a9.M12_MAX_SIGLE_TRAN_AMT,0) as M12_MAX_SIGLE_TRAN_AMT -- 近一年单笔最大交易金额
,nvl2(a9.M12_D_MAX_SIGLE_TRAN_AMT,a9.M12_D_MAX_SIGLE_TRAN_AMT,0) as M12_D_MAX_SIGLE_TRAN_AMT -- 近一年借方单笔最大交易金额
,nvl2(a9.M12_C_MAX_SIGLE_TRAN_AMT,a9.M12_C_MAX_SIGLE_TRAN_AMT,0) as M12_C_MAX_SIGLE_TRAN_AMT -- 近一年贷方单笔最大交易金额
,(case when nvl2(a10.M12_C_ALL_TRAN_AMT,a10.M12_C_ALL_TRAN_AMT,0) = 0 then -999999 else (a1.DEPO_BAL-a1.DEPO_BAL_20191130)/nvl2(a10.M12_C_ALL_TRAN_AMT,a10.M12_C_ALL_TRAN_AMT,0) end) as RETEN_RT -- 留存率
,'0' as Y1 --
,'0' as Y2 --
,(case when a1.LOAN_H_CNT>1 and a1.LOAN_BAL>0 then 1 else 0 end) as Y3 -- 是否近3年有过多次贷款且当前正在贷款的客户
from
(
select * from ana_tmp_t1 where BAD_DUE_FLG = '0'
) a1
LEFT JOIN
(
select distinct master_cust_no
from ADPXX_CQ_RECORD
where
(record_dt between 20171201 and 20201130) --近三年
and LIAB_PRDT_TYPE = '1'--取定期
group by master_cust_no
) a8 --取定期历史记录
ON a1.CUST_ID = a8.master_cust_no
LEFT JOIN ana_tmp_t2 a9
ON a1.CUST_ID = a9.CUST_ID
LEFT JOIN ana_tmp_t3 a10
ON a1.CUST_ID = a10.CUST_ID
;
alter table ANA_MARKETING_TMP add primary key (CUST_ID);
四 结论
在实际工作中,优化查询有时并不需要多么先进的理论和技术,而是根据工作需求找准清晰的目标和问题所在(业务拆分、关键信息提炼、数据整合),灵活使用基础技术即可达到目的。