0

我有两张桌子,必须检查一张桌子中的时间是否在其他桌子的范围之间。

ProgStartTime 给出范围的开始时间,ProgEndTime 给出位于 MBA 表中的范围的结束时间。我正在检查 MAP 表中的 AdvTime 是否存在于 MBA 表的 ProgStartTime 和 ProgEndTime 之间。

对于小于一小时的时间范围,我必须提供 + 或 - 5 分钟的缓冲区。

即如果 ProgStarttTime 是 18:00 & progEndTime 是 19:00 & AdvTime 是 17:55/19:05 它应该匹配范围。

而如果 ProgStarttTime 是 18:00 而 progEndTime 是 20:00 而 AdvTime 是 17:55 它不应该匹配。

抱歉内容有点匆忙。

我使用下面的查询来加入没有缓冲时间

SELECT DISTINCT mb.Id AS mbaid,
                mp.id AS mapid,
                mp.Channel AS Channel,
                mp.Product,
                mp.ProgDate,
                mp.AdvTime,
                mb.Channel,
                mb.ProgStartTime,
                mb.ProgEndTime,
                convert(time, dateadd(MINUTE, datediff(MINUTE, mb.progStartTime, mb.progEndTime), 0)) AS timeDiff
FROM map22 AS mp
INNER JOIN mba22 AS mb ON ((mp.ProgDate = mp.ProgDate
                            AND mp.Channel=mb.Channel
                            AND mp.Product=mb.Product))
WHERE (mp.ProgDate = mb.ProgDate
       AND AdvTime >= ProgStartTime
       AND (AdvTime <= ProgEndTime
            OR ProgEndTime < ProgStartTime))
  OR (mp.ProgDate = Dateadd(DAY,1,mb.ProgDate)
      AND ProgEndTime < ProgStartTime
      AND AdvTime <= ProgEndTime)
ORDER BY mp.Id ASC
4

1 回答 1

1

您的示例查询有很多内容,所以我创建了一个简化的示例。

设置数据:

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 与演示

于 2013-03-18T13:53:21.647 回答