如何筛选分区行号完整且指定行号日期在范围内的临时表数据
解决方案
要实现你需要的查询,核心是先筛选出满足两个条件的DocNo,再获取这些DocNo对应的所有行。以下是两种高效的实现方式:
方法一:子查询筛选目标DocNo
SELECT t1.* FROM TEMP1 t1 INNER JOIN ( -- 筛选出Rnk完整(包含1、2、3)且Rnk=3的TransDate在指定范围的DocNo SELECT DocNo FROM TEMP1 GROUP BY DocNo HAVING -- 确保该DocNo有3条完整的Rnk记录(1、2、3) COUNT(DISTINCT Rnk) = 3 -- 提取Rnk=3的TransDate并判断是否在指定范围内 AND MAX(CASE WHEN Rnk = 3 THEN TransDate END) BETWEEN '2023-08-01' AND '2023-08-10' ) t2 ON t1.DocNo = t2.DocNo ORDER BY t1.DocNo, t1.Rnk;
逻辑说明
- 子查询
t2负责筛选合格的DocNo:COUNT(DISTINCT Rnk) = 3:保证每个DocNo的Rnk值覆盖1、2、3三个序号;MAX(CASE WHEN Rnk = 3 THEN TransDate END):精准提取该DocNo下Rnk=3对应的日期,再判断是否在目标范围。
- 主查询通过
INNER JOIN关联原表,获取这些合格DocNo的所有行数据。
方法二:窗口函数一次性计算
WITH DocStats AS ( SELECT *, -- 统计每个DocNo的Rnk总数 COUNT(DISTINCT Rnk) OVER (PARTITION BY DocNo) AS RnkCount, -- 获取当前DocNo下Rnk=3的TransDate MAX(CASE WHEN Rnk = 3 THEN TransDate END) OVER (PARTITION BY DocNo) AS Rnk3TransDate FROM TEMP1 ) SELECT [Rnk (Row Number Partition by DocNo)], DocNo, TransDate FROM DocStats WHERE RnkCount = 3 AND Rnk3TransDate BETWEEN '2023-08-01' AND '2023-08-10' ORDER BY DocNo, [Rnk (Row Number Partition by DocNo)];
逻辑说明
- 公共表表达式
DocStats为每一行计算两个窗口结果:RnkCount:每个DocNo对应的不同Rnk数量;Rnk3TransDate:每个DocNo下Rnk=3对应的日期值;
- 后续查询直接基于这两个计算结果筛选,无需额外关联操作,逻辑更直观。
验证结果
当指定日期范围为2023-08-01到2023-08-10时,两种方法都会返回以下数据:
| Rnk (Row Number Partition by DocNo) | DocNo | TransDate |
|---|---|---|
| 1 | Doc1 | 1 Aug 2023 |
| 2 | Doc1 | 2 Aug 2023 |
| 3 | Doc1 | 3 Aug 2023 |
| 1 | Doc3 | 6 Aug 2023 |
| 2 | Doc3 | 7 Aug 2023 |
| 3 | Doc3 | 8 Aug 2023 |
注意事项
- 如果
TransDate是字符串类型,需要先转换为日期格式再判断范围,例如使用CONVERT(DATE, TransDate); - 可以直接替换
BETWEEN后的日期值,适配不同的查询范围需求。
内容的提问来源于stack exchange,提问作者Yoseph
相关产品推荐
相关产品推荐

