次のようなテーブルがあります。
code int, primary key
reservation_code int,
indate date,
outdate date,
slot int,
num int,
データベースにはやや奇妙な設計がされています。このテーブルが機能するはずの方法は、すべてのスロット予約の日付を保持することです。num は、レガシーの理由であると私が信じている連続した予約を追跡するために使用されます。
データベース内の以前の予約をチェックするクエリを考え出そうとしています。これを行う私の考え:
特定のスロット番号について、グループの最小 num 値を持つ行に、特定の日付以下の開始日と行の期限切れの日付を持つ、同じ reserved_code を持つ行のグループがあるかどうかを確認しますmax num 値が同じ日付よりも大きい。
SQLでこれに最も近いアプローチ:
編集:Barmarの助けを借りて
SELECT b.reservation_code
FROM bookings b
JOIN (SELECT reservation_code, MIN(num) minnum
FROM bookings
WHERE slot = "given_slot"
AND indate <= "given_date"
GROUP BY reservation_code) min
ON minnum = num and b.reservation_code = min.reservation_code
JOIN (SELECT reservation_code, MAX(num) maxnum
FROM bookings
WHERE slot = "given_slot"
AND outdate > "given_date"
GROUP BY reservation_code) max
ON maxnum = num and b.reservation_code = max.reservation_code
WHERE slot="given_slot"
AND indate <= "given_date"
AND outdate > "given_date"
GROUP BY b.reservation_code
両方のサブクエリに GROUP BY を追加すると、ほとんどの場合に機能しますが、2 番目のチェックでは依然として間違った回答が返されます。
質問をもう少し明確にするために、いくつかのサンプル行とクエリを次に示します。
サンプル行:
code reservation_code indate outdate slot num
1 1 01/01/13 03/01/13 1 0
2 1 03/01/13 05/01/13 1 1
3 1 05/01/13 10/01/13 1 2
4 2 04/01/13 15/01/13 2 0
5 2 15/01/13 19/01/13 2 1
6 3 11/01/13 13/01/13 1 0
7 4 15/01/13 16/01/13 3 0
8 5 01/01/13 15/01/13 3 0
9 5 15/01/13 25/01/13 4 1
サンプルチェック:
slot 2, date 21/02/13, should return not booked.
slot 2, date 16/01/13, should return booked
slot 1, date 14/01/13, should return not booked
slot 1, date 12/01/13, should return booked
slot 1, date 10/01/13, should return not booked
slot 3, date 02/01/13, should return booked
slot 4, date 15/01/13, should return booked
slot 4, date 25/01/13, should return not booked