基于变更获取产品的上一客户与当前客户
解决产品客户变更链的查询问题
看起来你需要构建一个从前一日最新客户到当日所有变更客户的连续链条,每个记录清晰展示「上一客户→当前客户」的变更关系。针对你的数据结构,我们可以通过排序+窗口函数(或递归CTE)来实现这个逻辑,下面是具体的解决方案:
步骤1:明确数据顺序规则
首先得理清CURR_DAY表的RANKING字段含义:值为1代表最新的变更,值越大代表变更发生得越早。所以我们需要先把CURR_DAY的记录按PROD_ID分组,再按RANKING降序排列,这样就能得到从早到晚的变更顺序(比如产品100的变更顺序是ABC→DEF)。
步骤2:查询SQL实现
这里提供两种可行的方案,你可以根据自己的习惯选择:
方案一:窗口函数LAG + 初始状态关联
这种方案用窗口函数快速获取上一客户,代码简洁高效:
WITH ordered_curr AS ( -- 给当日变更记录按「从早到晚」的顺序分配序号 SELECT PROD_ID, CUSTOMER, ROW_NUMBER() OVER (PARTITION BY PROD_ID ORDER BY RANKING DESC) AS change_seq FROM CURR_DAY ), change_chain AS ( SELECT oc.PROD_ID, -- 第一条变更的上一客户来自前一日数据,后续变更取前一条的当前客户 CASE WHEN oc.change_seq = 1 THEN pd.CUSTOMER ELSE LAG(oc.CUSTOMER) OVER (PARTITION BY oc.PROD_ID ORDER BY oc.change_seq) END AS PREV_CUST, oc.CUSTOMER AS CURRENT_CUST FROM ordered_curr oc JOIN PREV_DAY pd ON oc.PROD_ID = pd.PROD_ID ) SELECT PROD_ID, PREV_CUST, CURRENT_CUST FROM change_chain ORDER BY PROD_ID, change_seq;
方案二:递归CTE构建完整链条
如果想要更直观的链式逻辑展示,递归CTE会更易懂:
WITH ordered_curr AS ( -- 给当日变更记录分配顺序号,1代表最早的变更 SELECT PROD_ID, CUSTOMER, ROW_NUMBER() OVER (PARTITION BY PROD_ID ORDER BY RANKING DESC) AS change_seq FROM CURR_DAY ), recursive_chain AS ( -- 递归起点:第一条变更,上一客户直接关联前一日数据 SELECT pd.PROD_ID, pd.CUSTOMER AS PREV_CUST, oc.CUSTOMER AS CURRENT_CUST, oc.change_seq FROM PREV_DAY pd JOIN ordered_curr oc ON pd.PROD_ID = oc.PROD_ID WHERE oc.change_seq = 1 UNION ALL -- 递归后续:每条变更的上一客户是前一条变更的当前客户 SELECT oc.PROD_ID, rc.CURRENT_CUST AS PREV_CUST, oc.CUSTOMER AS CURRENT_CUST, oc.change_seq FROM ordered_curr oc JOIN recursive_chain rc ON oc.PROD_ID = rc.PROD_ID AND oc.change_seq = rc.change_seq + 1 ) SELECT PROD_ID, PREV_CUST, CURRENT_CUST FROM recursive_chain ORDER BY PROD_ID, change_seq;
执行结果
针对你提供的测试数据,两个方案都会返回以下符合预期的结果:
PROD_ID | PREV_CUST | CURRENT_CUST --------|-----------|------------- 100 | XYZ | ABC 100 | ABC | DEF 200 | EFG | IJK
完全匹配你想要的「PREV_CUST XYZ → CURRENT_CUST ABC,接着PREV_CUST ABC → CURRENT_CUST DEF」的变更链条逻辑。
关键逻辑说明
- 先用
ROW_NUMBER()给CURR_DAY的记录按变更时间顺序分配序号,确保变更链条的顺序正确; - 第一条变更的上一客户直接关联
PREV_DAY的历史客户; - 后续的变更通过
LAG()函数(或递归关联)获取前一条变更的客户作为上一客户,从而形成完整的变更链路。
内容的提问来源于stack exchange,提问作者user9256753
相关产品推荐
相关产品推荐

