ねえ、mySQL テーブルでのイベントのオーバーラップの解決策を探しているこのサイトに出くわしました。私は解決策にとても感銘を受けました(すでに役に立っています)。さらに助けが得られるかどうか見てみようと思いました...
さて、ジョーは職場の誰かとシフトを交換したいと思っています。彼には法廷の日付があります。彼はシフト スワップ フォームにアクセスし、今週のスケジュール (または残りのスケジュール) を表示します。これは、DB クエリで実行されます。汗かいていない。彼はシフトを選びます。ここから、チクチクします。
したがって、最初に、フォームはシフト開始とシフト終了をスクリプトに渡します。このシフトと重複するシフトを持っている人に対してクエリを実行します。一度に 2 つのシフトで働くことはできないため、このクエリのすべてのユーザー ID がブラック リストに登録されます。このクエリは次のようになります。
SELECT DISTINCT user_id FROM shifts
WHERE
FROM_UNIXTIME('$swap_shift_start') < shiftend
AND FROM_UNIXTIME('$swap_shift_end') > shiftstart
次に、a) 同じ長さ (会社のポリシー) であり、b) Joe が働いている他のシフトと重複しないすべてのシフトに対してクエリを実行します。
私が現在持っているものは次のようなものです:
SELECT *
FROM shifts
AND shiftstart BETWEEN FROM_UNIXTIME('$startday') AND FROM_UNIXTIME('$endday')
AND user_id NOT IN ($busy_users)
AND (TIME_TO_SEC(TIMEDIFF(shiftend,shiftstart)) = '$swap_shift_length')
$conflict_dates
ORDER BY shiftstart, lastname
さて、あなたはおそらく「$conflict_dates とは何か??」と疑問に思っているでしょう。
ジョーがスワップ シフトを送信すると、ジョーが別のシフトの可能性をチェックすることにした場合に備えて、その週のシフトがリロードされます。したがって、最初のクエリを実行すると、スクリプトがループして選択肢を出力している間に、次のような文字列も作成されます。
AND NOT(
'joe_shift1_start' < shiftend
AND 'joe_shift1_end' > shiftstart)
AND NOT(
'joe_shift2_start' < shiftend
AND 'joe_shift2_end' > shiftstart)
...etc
そのため、データベースは次の行に沿ってかなり長いクエリを取得しています。
SELECT *
FROM shifts
AND shiftstart BETWEEN FROM_UNIXTIME('$startday') AND FROM_UNIXTIME('$endday')
AND user_id NOT IN ('blacklisteduser1', 'blacklisteduser2',...etc)
AND (TIME_TO_SEC(TIMEDIFF(shiftend,shiftstart)) = '$swap_shift_length')
AND NOT(
'joe_shift1_start' < shiftend
AND 'joe_shift1_end' > shiftstart)
AND NOT(
'joe_shift2_start' < shiftend
AND 'joe_shift2_end' > shiftstart)
AND NOT(
'joe_shift3_start' < shiftend
AND 'joe_shift3_end' > shiftstart)
AND NOT(
'joe_shift4_start' < shiftend
AND 'joe_shift4_end' > shiftstart)
...etc
ORDER BY shiftstart, lastname
ですから、SQL がこれをより簡単な方法で処理する天才的な方法を持っているか、誰かが潜在的な競合をよりスマートな方法で説明する素晴らしい論理プリンシパルを指摘できることを願っています。(「開始 > 終了、終了 < 開始」の使用に注意してください。その間に使用していたことがわかり、両端から 1 分を差し引く必要がありました。)
ありがとう!
あ