如何通过条件LEAD()获取各Account_ID的首个有效Sales_Date?
问题描述
需要为每个ACCOUNT_ID获取首个有效销售日期,规则如下:
- 有效销售日期需排除样本产品记录(样本产品定义为
REVENUE=0或PRODUCT_DESCRIPTION包含Sample) - 若某个
ACCOUNT_ID的最早销售日期中存在样本产品,需跳过该日期,取后续首个无样本产品的销售日期 - 原查询因未处理“同一日期同时包含样本与实际产品”的场景,导致输出出现重复
ACCOUNT_ID行,需修正查询以得到正确结果
原查询语句
WITH UNIQUE_ID AS( SELECT DISTINCT ACCOUNT_ID, MIN(SALES_DATE) FIRST_SALES_DATE FROM Sample_Data_Table GROUP BY ACCOUNT_ID ) SELECT ACCOUNT_ID, ( CASE WHEN PRODUCT_DESCRIPTION LIKE ('%Sample%') THEN LEAD (SALES_DATE,1,NULL) OVER (PARTITION BY ACCOUNT_ID ORDER BY ACCOUNT_ID ASC) END ) NEW_FIRST_SALES_DATE FROM UNIQUE_ID
(注:原查询存在逻辑错误:CTE仅取了每个账号的最早日期,但未关联原表产品信息,且LEAD函数排序逻辑错误,无法正确跳过含样本的日期)
样本数据表(Sample_Data_Table)
| ACCOUNT_ID | ACCOUNT_NAME | PRODUCT_DESCRIPTION | REVENUE | SALES_DATE |
|---|---|---|---|---|
| 1 | A | Sample A | 0 | 2005-01-05 |
| 1 | A | Product B | 253 | 2005-01-05 |
| 3 | C | Product C | 1654 | 2005-02-05 |
| 4 | D | Product D | 316 | 2005-03-08 |
| 5 | E | Product E | 123 | 2005-04-08 |
| 6 | F | Product F | 587 | 2005-05-09 |
| 7 | G | Product G | 987 | 2005-06-09 |
| 8 | H | Product H | 58 | 2005-07-10 |
| 9 | I | Product I | 65 | 2005-08-10 |
| 10 | J | Product J | 2189 | 2005-09-10 |
| 1 | A | Product P | 6 | 2006-03-15 |
期望结果
| ACCOUNT_ID | NEW_FIRST_SALES_DATE |
|---|---|
| 3 | 2005-02-05 |
| 4 | 2005-03-08 |
| 5 | 2005-04-08 |
| 6 | 2005-05-09 |
| 7 | 2005-06-09 |
| 8 | 2005-07-10 |
| 9 | 2005-08-10 |
| 10 | 2005-09-10 |
| 1 | 2006-03-15 |
修正后的查询语句
分两步处理逻辑,确保准确筛选首个有效销售日期:
WITH Date_Validation AS ( SELECT ACCOUNT_ID, SALES_DATE, -- 标记该日期是否包含样本产品 MAX(CASE WHEN REVENUE = 0 OR PRODUCT_DESCRIPTION LIKE '%Sample%' THEN 1 ELSE 0 END) OVER (PARTITION BY ACCOUNT_ID, SALES_DATE) AS has_sample FROM Sample_Data_Table ), Valid_Dates AS ( SELECT ACCOUNT_ID, SALES_DATE, -- 按日期排序,给首个无样本的日期标记序号1 ROW_NUMBER() OVER (PARTITION BY ACCOUNT_ID ORDER BY SALES_DATE ASC) AS rn FROM Date_Validation WHERE has_sample = 0 ) SELECT ACCOUNT_ID, SALES_DATE AS NEW_FIRST_SALES_DATE FROM Valid_Dates WHERE rn = 1 ORDER BY ACCOUNT_ID;
查询逻辑说明
- Date_Validation CTE:对每个账号的每个销售日期,判断该日期下是否存在样本产品(只要该日期有一条样本记录,就标记为1)
- Valid_Dates CTE:筛选出所有不含样本的日期,为每个账号按日期排序,给首个有效日期标记
rn=1 - 最终取出每个账号
rn=1的日期,即为所需的首个有效销售日期
执行该查询后,将得到与期望完全一致的结果,且每个ACCOUNT_ID仅返回一行,解决了原查询的重复行问题。
内容的提问来源于stack exchange,提问作者Ludicium
相关产品推荐
相关产品推荐

