0

2 つのテーブルがあり、テーブルの時間が他のテーブルの範囲内にあるかどうかを確認する必要があります。

ProgStartTime は範囲の開始時間を示し、ProgEndTime は MBA テーブルにある範囲の終了を示します。MBA テーブルの ProgStartTime と ProgEndTime の間に MAP テーブルの AdvTime が存在するかどうかを確認しています。

1 時間未満の時間範囲の場合、+ または - 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 ステートメントを適用して、日付の差が 1 時間以下の場合に 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

結果が得られます:

ここに画像の説明を入力

継続時間が 1 時間の MBA 1 では、AdvTime の値がわずかに前後で一致していることがわかりますが、MBA 2 では、必要に応じて期間内の値のみが一致しています。

demo を使用した 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'

元のクエリは、予想どおり上記の行の両方に一致します。

demo を使用した 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'

それでも予想通りのマッチング。

demo を使用した SQL Fiddle

コメント後の最終編集?

OK、スキーマについてもう少し理解できたので、最後のクエリを 1 つ作成できます。データを設定します。

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

結果:

ここに画像の説明を入力

demo を使用した SQL Fiddle

于 2013-03-18T13:53:21.647 に答える