You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle表中存在日期范围重叠的员工履历记录查询咨询

找出Oracle表中存在履历日期重叠的员工注册编号

嘿,这个问题很常见,我来给你详细讲讲怎么解决!要找出存在日期范围重叠记录的Registration_No,我们不需要特别冷门的Oracle函数,用基础的日期比较、自连接或者分析函数就能搞定,下面给你两种实用的方法:

方法一:自连接查询(直观易懂)

这种方式是把表和自己做连接,匹配同一员工的不同履历记录,判断它们的日期范围是否重叠。

实现SQL

SELECT DISTINCT a.REGISTRATION_NO
FROM A a
INNER JOIN A b
  ON a.REGISTRATION_NO = b.REGISTRATION_NO
  AND a.ROWID <> b.ROWID -- 排除同一条记录自己匹配自己的情况
  AND a.JOIN_DATE < b.RESG_DATE
  AND b.JOIN_DATE < a.RESG_DATE;

逻辑解释

  • 用REGISTRATION_NO关联同一员工的不同记录,ROWID <> b.ROWID避免同一条记录自我匹配;
  • 核心的重叠判断条件:两个日期区间[a.JOIN_DATE, a.RESG_DATE]和[b.JOIN_DATE, b.RESG_DATE]重叠的标准是**a的入职日期 < b的离职日期 且 b的入职日期 < a的离职日期**,这个条件能覆盖所有重叠场景(包含、交叉等);
  • DISTINCT用来去重,因为同一员工的重叠记录会被双向匹配两次,去重后得到唯一的员工编号。

方法二:分析函数LAG(高效简洁)

如果数据量较大,用分析函数LAG会更高效,它能帮我们在分组排序后直接获取上一条记录的离职日期,然后和当前记录的入职日期做比较。

实现SQL

SELECT DISTINCT REGISTRATION_NO
FROM (
  SELECT 
    REGISTRATION_NO,
    JOIN_DATE,
    RESG_DATE,
    -- 按员工分组、入职日期排序,获取上一条记录的离职日期
    LAG(RESG_DATE) OVER (PARTITION BY REGISTRATION_NO ORDER BY JOIN_DATE) AS PREV_RESIGN_DATE
  FROM A
) t
-- 如果当前入职日期早于上一条的离职日期,说明两条履历重叠
WHERE JOIN_DATE < PREV_RESIGN_DATE;

逻辑解释

  • LAG(RESG_DATE) OVER (PARTITION BY REGISTRATION_NO ORDER BY JOIN_DATE):这个分析函数的作用是,把数据按REGISTRATION_NO分组,每组内按JOIN_DATE排序,然后给每条记录添加上一条记录的RESG_DATE;
  • 外层查询中,只要当前记录的JOIN_DATE小于上一条的PREV_RESIGN_DATE,就说明这两条履历的日期范围有重叠;
  • 同样用DISTINCT去重,确保每个员工编号只出现一次。

验证你的示例数据

用你提供的测试数据执行上面任意一个SQL,都会得到结果:100和102,这正好对应你提到的有重叠的黄色标记区域,完美符合预期。

关于Oracle函数的说明

这里用到的LAG是Oracle的分析函数,专门用于处理分组排序后相邻记录的比较,非常适合这类场景。除此之外,我们只用到了基础的日期比较逻辑,不需要额外的特殊日期函数——如果你的数据是字符串格式,可能需要用TO_DATE转换,但你的示例数据已经是DATE类型,所以直接用即可。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:41:59