1

2 つのテーブル間でデータを比較し、競合がないかどうかを確認する必要があります。

以下は、競合しているレコードに基づいてテーブルとテーブルEvents & Bookingsを比較する必要がある2つのテーブルのサンプルデータです。bookingsEventsDate & Time

実際には、日付が変更されたら、ユーザーはイベントの日付と時刻を変更できます。ユーザーは、その特定の日付と時間枠の予約が既にあるかどうかを示すレポートを生成する必要があります。

次のクエリを使用して、更新されたイベントの予約があるかどうかを確認しています

クエリ

Declare @bTime varchar(10) = '10:30';
Declare @bDate date = '2012-08-15';
SELECT * FROM  EventDatesReporting   WHERE 
((CONVERT(time(0), EventStartTime) <= CONVERT(time(0),@bTime )  
    AND CONVERT(time(0), EventEndTime) >= CONVERT(time(0),@bTime ))
OR 
(CONVERT(time(0), EventStartTime) <= DATEADD(minute,59,CONVERT(time(0), @bTime))   
    AND CONVERT(time(0), EventEndTime) >= DATEADD(minute,59,CONVERT(time(0), @bTime))))
AND EventDates = @bDate

上記のクエリは正常に機能しますが、Booking テーブルBookingDate & Timeと比較できるように、このクエリを変換する必要がありEvents Tableます。これらのテーブルのデータは時間とともに大きくなる可能性があるため、パフォーマンス ベースの ms sql-query を探しています。

イベント

EventID EventStartDate  EventEndDate    EventDates  DT        EventStartTime    EventEndTime
17      2012-07-25      2012-07-26      2012-07-25  2012-07-25  10:00:00        12:00:00
17      2012-07-25      2012-07-26      2012-07-26  2012-07-26  10:00:00        12:00:00
21      2012-05-28      2012-05-28      2012-05-28  2012-05-28  18:00:00        19:00:00
26      2012-01-01      2015-01-01      2012-07-01  2012-07-01  08:00:00        18:00:00

予約

BookingID   TotalVisitors   BookingDate Time    BookingCancelled
1900221519  5               2012-07-10  10:30   0
5600515751  1               2012-07-20  10:30   0
8044913913  41              2012-07-05  10:30   0
1638934678  5               2012-07-20  10:30   1
5685687635  9               2012-07-25  10:30   0

上記のケースでは、ユーザーが最初のイベントの日付を変更したと仮定しますが 2012-07-25、この日付に予約があるため、予約テーブルと競合します。ユーザーが予約のキャンセルについて親密なユーザーなど、それに応じてアクションを実行できるように、そのような行を見つける必要があります。

シナリオ&詳細

月曜日から金曜日まで、午前 10 時 30 分と午後 4 時 30 分の 2 つの異なる時間に、プライベート ミュージアムとしましょう。ツアーごとに最大 50 人のビジターを受け入れることができます。 )。50 人のグループが 2012 年 8 月 15 日の午前 10 時 30 分に博物館を訪れたいと仮定すると、フロント エンドでこの日付をブロックします。フロント エンドは、名前、住所、会社名、訪問者数、時間 (午前 10 時 30 分、午後 4 時 30 分という 2 つのエントリを含むドロップダウン) および訪問日 (カレンダー コントロール) などの共通フィールドを備えたシンプルな Web フォームです。満席に達した日付をブロックし、利用可能な日付のみを選択できるようにします。

反対側では、博物館も特別なイベントを開催しており、予約フォームでそれらの日付をブロックすることができます. 2012 年 8 月 10 日の午前 9:00 ~ 午後 1:00 に予定されていたイベントが、管理者によって以前にブロックされたとします。イベントの日付が 2012-08-25 に変更されました。以前はこの日付にイベントが予定されていなかったため、博物館にはこの日付の予約がいくつかありました。

博物館は、2012 年 8 月 25 日に同じ日に予約をした人のツアーに参加できないため、通知する必要があります。このために、2 つのテーブル イベント テーブルと予約テーブルを比較し、2012 年 8 月 25 日の 10:30 に予約があるかどうかを調べます。ある場合は、ツアーのキャンセルについて電子メールで訪問者に知らせる必要があります。

私のクエリでは、EventStartTime と EventEndTime の間に少なくとも 1 時間の休憩が必要なため、時間に 59 分を追加しています。

これにより、レポートを探しているデータの種類がわかると思います。私が言及したクエリは正常に機能しますが、予約テーブルの各行の日付と時刻の値を予約テーブルからイベント テーブルに渡し、予約テーブルから eventDate & time と衝突するレコードのみを表示する必要があります

望ましい出力 サンプル データから、イベントの日付が変更された後に予約と競合するかのようにのみ次のレコードを表示するクエリが必要です

EventID BookingID   TotalVisitors   BookingDate Time    BookingCancelled
17      5685687635  9               2012-07-25  10:30   0
4

1 に答える 1

2

+1 時間は、実際には博物館への訪問が 1 時間続くことを意味し、この 1 時間が他の博物館の活動と重複してはならないことを意味すると仮定すると、そのような衝突を見つけるクエリは次のとおりです。キャンセルされていない予約については、予約/イベントの日付に関する 2 つのテーブル間の単純な結合です。オーバーラップ間隔は、ここで説明する式を使用してチェックされます。基本的に、2 つの範囲は、範囲 A の開始日が範囲 B の終了日より前であり、範囲 A の終了日が範囲 B の開始日より後に重複していAfterますbeforeafter or equalsbefore or equals

select e.EventID,
       b.BookingID,
       b.TotalVisitors,
       b.BookingDate,
       b.Time,
       b.BookingCancelled
  from EventDatesReporting e
 inner join Bookings b
   -- On same date
    on e.EventDates = b.BookingDate
   -- Overlapping intervals
   and e.EventEndTime >= cast(b.Time as Time)
   and e.EventStartTime < dateadd (hour, 1, cast(b.Time as Time))
   -- Only if booking is not cancelled
   and b.BookingCancelled = 'false'

Sql Fiddle という便利な SQL サイトがあります。オンラインで確認できるように、サンプルと私の回答をそこに置きました。

于 2012-07-16T11:17:26.047 に答える