You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动