SQL Server:筛选满足双表日期条件的TABLE_A记录ID
解决TABLE_A筛选符合特定日期条件的ID问题
嘿,我来帮你搞定这个SQL查询问题!你提到考虑过用OVER(PARTITION BY)窗口函数,这个方向完全正确,咱们直接把思路落地成可执行的解决方案。
首先明确咱们要筛选的核心条件:
- 找到
TABLE_A.startDate之后至少10天的首个TABLE_B.calendarDay,且该日期的open值为1; TABLE_A.endDate必须和这个找到的首个日期完全匹配。
方法一:使用窗口函数(推荐,逻辑清晰)
我们可以通过CTE(公共表表达式)先关联两张表,筛选出符合时间范围和open=1的日期,再用窗口函数给每个ID的候选日期排序,最后筛选出首个日期与endDate匹配的记录:
WITH eligible_dates AS ( SELECT a.id, a.startDate, a.endDate, b.calendarDay, -- 按日期升序排序,给每个ID的候选日期排名 ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY b.calendarDay ASC) AS rn FROM TABLE_A a JOIN TABLE_B b ON b.calendarDay >= DATE_ADD(a.startDate, INTERVAL 10 DAY) -- 满足startDate后10天或更晚 AND b.open = 1 -- 仅保留open=1的日期 ) SELECT id, startDate, endDate FROM eligible_dates WHERE rn = 1 -- 取每个ID的首个符合条件的日期 AND calendarDay = endDate; -- 确保该日期与endDate一致
方法二:使用双重EXISTS子查询
如果你的SQL环境对CTE支持有限,也可以用双重EXISTS来实现逻辑:
SELECT a.id, a.startDate, a.endDate FROM TABLE_A a WHERE EXISTS ( -- 首先验证endDate本身是open=1且在startDate+10天后的日期 SELECT 1 FROM TABLE_B b1 WHERE b1.calendarDay = a.endDate AND b1.open = 1 AND b1.calendarDay >= DATE_ADD(a.startDate, INTERVAL 10 DAY) -- 其次验证endDate是startDate+10天后的第一个open=1的日期 AND NOT EXISTS ( SELECT 1 FROM TABLE_B b2 WHERE b2.calendarDay > DATE_ADD(a.startDate, INTERVAL 10 DAY) AND b2.calendarDay < b1.calendarDay AND b2.open = 1 ) );
验证示例数据
用你提供的示例数据测试这两个查询,都会得到期望的结果:
+----+------------+------------+ | id | startDate | endDate | +----+------------+------------+ | 1 | 2011-02-14 | 2011-03-14 | | 2 | 2012-12-19 | 2013-01-20 | +----+------------+------------+
内容的提问来源于stack exchange,提问作者Benjamin Andersen




