基于条件统计贷款周期及并行贷款场景的SQL优化需求
解决方案:使用窗口函数实现贷款周期统计
需求回顾
- 为每个客户的每条贷款记录生成
cycle:按贷款顺序从1开始连续编号 - 生成
p_cycle:若客户仅1条记录则为0,否则为cycle - 1 - 需支持并行在贷场景的正确统计
原SQL问题分析
原SQL通过关联子查询匹配前序贷款的最大dat_last_mnt,但并行贷款时,多条记录可能存在dat_acct_open无严格先后、或前序贷款未结清(dat_last_mnt未更新)的情况,导致关联逻辑失效,统计出的p_cycle出现错误(如多条记录的p_cycle均为同一值)。
优化后的SQL实现
利用窗口函数可以直接按客户分组并排序,无需复杂关联,完美解决并行贷款场景的统计问题:
SELECT cod_cust_id, -- 按客户分组,按开户日期+首次放款日期排序生成cycle编号 ROW_NUMBER() OVER (PARTITION BY cod_cust_id ORDER BY dat_acct_open, dat_first_disb) AS cycle, -- 处理单条记录的特殊情况,其余直接取cycle-1 CASE WHEN COUNT(*) OVER (PARTITION BY cod_cust_id) = 1 THEN 0 ELSE ROW_NUMBER() OVER (PARTITION BY cod_cust_id ORDER BY dat_acct_open, dat_first_disb) - 1 END AS p_cycle FROM acct_dtls WHERE dat_first_disb IS NOT NULL -- 过滤未放款的账户,与原逻辑一致 ORDER BY cod_cust_id, cycle;
代码说明
PARTITION BY cod_cust_id:将数据按客户分组,确保每个客户的贷款记录单独统计ROW_NUMBER()窗口函数:为每个客户的贷款记录按dat_acct_open(开户日期)和dat_first_disb(首次放款日期)排序,生成从1开始的唯一连续编号作为cycleCASE语句:判断客户的总贷款数,若仅1条则p_cycle设为0,否则直接计算cycle - 1- 过滤条件:保留有放款记录的账户,与原SQL逻辑对齐
优势
- 无需复杂关联和子查询,逻辑清晰易维护
- 不受并行贷款影响,无论贷款是否同时在贷,只要能通过日期字段排序,就能正确生成
cycle和p_cycle - 执行效率更高,窗口函数的性能通常优于多表关联+子查询的组合
内容的提问来源于stack exchange,提问作者Shodmoni Hikmatullozoda
相关产品推荐
相关产品推荐

