2013-03-18 43 views
0

我有兩個表,並且必須檢查表中的時間是否位於其他表的範圍之間。SQL加入緩衝時間

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它不應該匹配。

對不起,有點匆忙的笨拙的內容。

我用下面的查詢加盟wihtout緩衝時間

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 

回答

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 

給出的結果:

enter image description here

我們可以SE e對於工作時間爲1小時的MBA 1,我們在前後稍微匹配AdvTime值,但對於MBA 2,只需根據需要匹配時間段內的值。

SQL Fiddle with demo。評論後

編輯:

增加了另一個例子在註釋中的值,用以下數據:

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 with demo。評論後

編輯:

測試更多的數據:

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 with demo

評論後的最終編輯?

好的,現在我們知道更多關於模式的信息,我們可以做出最後一個查詢。設置數據:

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 

結果:

enter image description here

SQL Fiddle with demo

+0

謝謝你的時間。 我需要另一種方案來解決問題。 當持續時間(ProgStartTime - ProgEndTime)是一個小時或更少時,我需要一個+或 - 5分鐘的緩衝區。 如果我的ProgstartTime和ProgEndtime是21:00:00至22:00:00。 我需要20:55:00/22:05:00來匹配範圍。 – 2013-03-18 17:54:22

+0

原始查詢也適用於上述值。我已經添加了一個SQL小提琴演示這個。 – 2013-03-18 18:45:33

+0

道歉的困惑> 考慮以下情況 StartTme 23:00結束時間02:00 AdvTime 00:30我需要它匹配範圍。 我先前用下面的代碼,爲此目的從MBA 內 選擇* 上加入地圖 MBA.ProgStartTime <= 情況下,當DATEDIFF(MI,MBA.ProgStartTime,MBA.ProgEndTime)<= 60 然後DATEADD( MI,5,Map.AdvTime) 別的Map.AdvTime 端 和MBA.ProgEndTime> = 情況下,當DATEDIFF(MI,MBA.ProgStartTime,MBA.ProgEndTime)<= 60 然後DATEADD(MI,-5,地圖.AdvTime) else Map.AdvTime end – 2013-03-18 18:56:03