您的示例查询有很多内容,所以我创建了一个简化的示例。
设置数据:
create table MBA (MBAID int, ProgStartTime datetime, ProgEndTime datetime)
insert into MBA select 1, '20130318 18:00:00', '20130318 19:00:00'
insert into MBA select 2, '20130318 18:00:00', '20130318 20:00:00'
create table Map (MapID int, AdvTime datetime)
insert into Map select 1, '20130318 17:55:00'
insert into Map select 2, '20130318 18:30:00'
insert into Map select 3, '20130318 19:05:00'
insert into Map select 4, '20130318 20:05:00'
基于此,我们可以应用 CASE 语句在日期之间的差异为一小时或更短时为 AdvTime 提供更松散的匹配:
select *
from MBA
inner join Map on
MBA.ProgStartTime <=
case when datediff(mi, MBA.ProgStartTime, MBA.ProgEndTime) <= 60
then dateadd(mi, 5, Map.AdvTime)
else Map.AdvTime
end
and MBA.ProgEndTime >=
case when datediff(mi, MBA.ProgStartTime, MBA.ProgEndTime) <= 60
then dateadd(mi, -5, Map.AdvTime)
else Map.AdvTime
end
给出结果:
我们可以看到,对于持续时间为一小时的 MBA 1,我们在前后稍微匹配 AdvTime 值,但对于 MBA 2,仅根据需要匹配时间段内的值。
SQL Fiddle 与演示。
评论后编辑:
为注释中的值添加了另一个示例,其中包含以下数据:
create table MBA (MBAID int, ProgStartTime datetime, ProgEndTime datetime)
insert into MBA select 1, '20130318 21:00:00', '20130318 22:00:00'
create table Map (MapID int, AdvTime datetime)
insert into Map select 1, '20130318 20:55:00'
insert into Map select 2, '20130318 22:05:00'
原始查询按预期匹配上述两行。
SQL Fiddle 与演示。
评论后编辑:
用更多数据测试:
create table MBA (MBAID int, ProgStartTime datetime, ProgEndTime datetime)
insert into MBA select 1, '20130318 23:00:00', '20130319 02:00:00'
create table Map (MapID int, AdvTime datetime)
insert into Map select 1, '20130319 00:30:00'
仍然符合预期。
SQL Fiddle 与演示。
评论后的最终编辑?
好的,现在我们对可以进行最终查询的架构有了更多了解。设置数据:
create table MBA (MBAID int, ProgStartTime datetime, ProgEndTime datetime)
insert into MBA select 1, '18:00:00', '19:00:00'
insert into MBA select 2, '18:00:00', '20:00:00'
insert into MBA select 3, '21:00:00', '22:00:00'
insert into MBA select 4, '23:30:00', '02:00:00'
insert into MBA select 5, '23:30:00', '00:30:00'
create table Map (MapID int, AdvTime datetime)
insert into Map select 1, '17:55:00'
insert into Map select 2, '18:30:00'
insert into Map select 3, '19:05:00'
insert into Map select 4, '20:05:00'
insert into Map select 5, '20:55:00'
insert into Map select 6, '22:05:00'
insert into Map select 7, '23:25:00'
insert into Map select 8, '23:30:00'
insert into Map select 9, '00:30:00'
insert into Map select 10, '00:35:00'
使用以下查询:
select *
from MBA
inner join Map on
(MBA.ProgStartTime < MBA.ProgEndTime
and MBA.ProgStartTime <=
case when datediff(mi, MBA.ProgStartTime, MBA.ProgEndTime) <= 60
then dateadd(mi, 5, Map.AdvTime)
else Map.AdvTime
end
and MBA.ProgEndTime >=
case when datediff(mi, MBA.ProgStartTime, MBA.ProgEndTime) <= 60
then dateadd(mi, -5, Map.AdvTime)
else Map.AdvTime
end) or
(MBA.ProgStartTime > MBA.ProgEndTime
and (MBA.ProgStartTime <=
case when 1440 - datediff(mi, MBA.ProgEndTime, MBA.ProgStartTime) <= 60
then dateadd(mi, 5, Map.AdvTime)
else Map.AdvTime
end
or MBA.ProgEndTime >=
case when 1440 - datediff(mi, MBA.ProgEndTime, MBA.ProgStartTime) <= 60
then dateadd(mi, -5, Map.AdvTime)
else Map.AdvTime
end))
我们希望匹配以下行:
MBA Matched Maps
1 1,2,3
2 2,3
3 5,6
4 8,9,10
5 7,8,9,10
结果:
SQL Fiddle 与演示。