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

如何在SQL Server中筛选并排除完全被包含的日期范围数据?

我来帮你搞定这个日期范围过滤的需求~先把你提供的map表数据整理成更直观的表格:

原始map表数据

sedcodeidstartdateenddate
1011019A2002-12-022009-11-17
1011019B1986-01-022009-11-04
1011019C2009-07-012009-11-17
1011019C2002-12-022009-06-30
1011019D1986-01-032009-11-17
1011019E2007-10-152009-11-17
1011019E1992-01-311999-08-30
1011019F2007-11-262009-11-05
1011019F2007-09-052007-11-22
1011019F2007-07-062007-09-03

你的需求是:排除那些被同组(sedcode相同)内其他行完全包含日期范围的记录,也就是只保留“没有任何其他行能把它的日期范围全包住”的行。

可行的SQL查询方案

NOT EXISTS子查询就能精准实现这个逻辑,代码如下:

SELECT m1.*
FROM map m1
WHERE NOT EXISTS (
    SELECT 1
    FROM map m2
    -- 限定同一sed和code分组
    WHERE m2.sed = m1.sed
      AND m2.code = m1.code
      -- m2的日期范围完全包含m1的
      AND m2.startdate <= m1.startdate
      AND m2.enddate >= m1.enddate
      -- 排除自己和自己比较的情况(避免误判相同的行)
      AND NOT (
          m2.id = m1.id
          AND m2.startdate = m1.startdate
          AND m2.enddate = m1.enddate
      )
);

逻辑解释

  1. 外层查询遍历map表的每一行(记为m1
  2. 内层子查询检查:在同一sedcode的分组里,是否存在另一行(记为m2),满足m2的开始日期更早、结束日期更晚,而且m2不是m1本身
  3. 如果不存在这样的m2,就保留m1这条记录;如果存在,就排除它

结果验证

按照你的数据,最终会保留的行是:

  • B行:它的开始日期(1986-01-02)比D行的更早,没有任何行能完全包含它
  • D行:它的日期范围是最宽的,没有其他行能包含它

其他行都会因为被D行(或其他更宽的行)完全包含而被排除。

另外,如果你的表有唯一主键(比如自增的row_id),可以把最后那个排除自身的条件换成m2.row_id != m1.row_id,这样会更简洁准确。

内容的提问来源于stack exchange,提问作者koala

火山引擎 最新活动