SQL查询需求:同一客户分组下筛选日期差≥3天的行
问题:筛选客户记录,仅移除同一客户下日期差小于3天的行
我需要查询数据,保留同一客户(对应title字段)下日期差≥3天的行,以及仅存在单条记录的客户行,只移除同一客户下日期差小于3天的行。
原始数据表(AgendaSaidas)
| id | title | end |
|---|---|---|
| 1 | 763 | 2023-01-11 |
| 2 | 763 | 2023-01-08 |
| 3 | 763 | 2023-01-07 |
| 4 | 545 | 2023-01-01 |
| 5 | 545 | 2023-01-08 |
| 6 | 323 | 2023-01-07 |
当前使用的查询语句
WITH cte1 AS ( SELECT title, DATE(end) AS Regresso FROM AgendaSaidas ), cte2 AS ( SELECT title, Regresso, DATEDIFF(LEAD(Regresso) OVER (ORDER BY Regresso), Regresso) delta FROM cte1 ) SELECT title, Regresso FROM cte2 WHERE delta >= 3 OR delta IS NULL;
当前错误返回结果
| id | title | end |
|---|---|---|
| 1 | 763 | 2023-01-11 |
| 2 | 763 | 2023-01-08 |
| 4 | 545 | 2023-01-01 |
该语句错误移除了客户545的第二条记录(id=5),还漏掉了单条记录的客户323(id=6),原因是LEAD函数未按title分区,导致跨客户计算日期差,同时逻辑未正确覆盖所有需要保留的情况。
正确预期结果
| id | title | end |
|---|---|---|
| 1 | 763 | 2023-01-11 |
| 2 | 763 | 2023-01-08 |
| 4 | 545 | 2023-01-01 |
| 5 | 545 | 2023-01-08 |
| 6 | 323 | 2023-01-07 |
仅需移除id=3的行,因为它和同一客户(title=763)的下一条记录(id=2)日期差仅1天,小于3天。
修正后的查询语句
WITH cte AS ( SELECT id, title, DATE(end) AS Regresso, -- 按客户分区、日期排序,获取下一条记录的日期 LEAD(DATE(end)) OVER (PARTITION BY title ORDER BY DATE(end)) AS next_regresso, -- 统计每个客户的总记录数 COUNT(*) OVER (PARTITION BY title) AS record_count FROM AgendaSaidas ) SELECT id, title, Regresso AS end FROM cte WHERE -- 保留单条记录的客户 record_count = 1 -- 保留与下一条记录日期差≥3天的行 OR DATEDIFF(next_regresso, Regresso) >= 3 -- 保留客户的最后一条记录(无后续记录无需对比) OR next_regresso IS NULL;
关键修正说明
- 分区计算:通过
PARTITION BY title让LEAD和COUNT函数仅在同一客户内部计算,避免跨客户干扰。 - 单条记录保留:用
record_count = 1直接筛选出只有一条记录的客户,全部保留。 - 完整保留逻辑:覆盖三种必须保留的情况,确保不会遗漏或错误删除数据。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

