SQL中根据培训起止日期匹配最贴合的在职资源
解决方案:筛选培训期间在职且贴合度最高的资源
我来帮你搞定这个SQL报表的需求~首先得明确核心逻辑:我们要找的是在整个培训周期内全程在职,并且在职时间段和培训时间最贴合的资源(比如例子里的Emp4,入职刚好是培训开始日,离职在培训结束之后,这种就是最优匹配)。
先分析你现有SQL的问题
你原来的语句有两个关键缺陷:
- 筛选条件太窄:只匹配了入职月份和培训开始月份相同、或离职月份和培训结束月份相同的资源,会漏掉大量真正在职的资源;
- 排序逻辑不完整:只按
TerminatedOn倒序,没有考虑入职时间和培训开始的贴合度,没法选出最匹配的资源。
正确的SQL实现方案
下面是针对SQL Server的实现(如果是其他数据库,语法细节稍作调整即可):
-- 定义培训起止日期参数(建议用参数,方便复用) DECLARE @TrainingStart DATE = '2017-08-01'; DECLARE @TrainingEnd DATE = '2017-08-04'; SELECT TOP 1 R.FullName FROM [Resource] R WHERE -- 核心条件:确保资源在整个培训期间全程在职 R.JoinedOn <= @TrainingStart AND (R.TerminatedOn IS NULL OR R.TerminatedOn >= @TrainingEnd) ORDER BY -- 优先级1:入职日期完全匹配培训开始日(最贴合) CASE WHEN R.JoinedOn = @TrainingStart THEN 1 ELSE 0 END DESC, -- 优先级2:离职日期完全匹配培训结束日 CASE WHEN R.TerminatedOn = @TrainingEnd THEN 1 ELSE 0 END DESC, -- 优先级3:入职日期越晚(越接近培训开始)越靠前 R.JoinedOn DESC, -- 优先级4:离职日期越早(越接近培训结束)越靠前 R.TerminatedOn ASC;
逻辑说明
筛选条件:
R.JoinedOn <= @TrainingStart:资源入职时间不晚于培训开始日,保证培训开始时已在职;(R.TerminatedOn IS NULL OR R.TerminatedOn >= @TrainingEnd):资源要么还在职(TerminatedOn为空),要么离职时间不早于培训结束日,保证培训结束时仍在职。
这两个条件结合,确保资源在整个培训周期内全程在职。
排序逻辑:
按照贴合度从高到低排序:- 先挑入职日和培训开始日完全一致的资源(比如你的例子中的Emp4);
- 再挑离职日和培训结束日完全一致的资源;
- 如果没有完全匹配的,就选入职时间最接近培训开始、同时离职时间最接近培训结束的资源。
可选调整
如果你的需求是“培训期间内至少有一天在职”(而非全程在职),只需要把WHERE条件改成:
WHERE R.JoinedOn <= @TrainingEnd AND (R.TerminatedOn IS NULL OR R.TerminatedOn >= @TrainingStart)
如果有多个资源贴合度相同(比如两个资源都是入职等于培训开始、离职等于培训结束),可以在ORDER BY最后加上R.Id ASC来保证结果的稳定性。
内容的提问来源于stack exchange,提问作者55SK55
相关产品推荐
相关产品推荐

