これは古典的な問題であり、論理を逆にすると実際には簡単になります。
例を挙げましょう。
ここに1つの期間を投稿し、他の期間のさまざまなバリエーションはすべて、何らかの形で重複しています。
|-------------------| compare to this one
|---------| contained within
|----------| contained within, equal start
|-----------| contained within, equal end
|-------------------| contained within, equal start+end
|------------| not fully contained, overlaps start
|---------------| not fully contained, overlaps end
|-------------------------| overlaps start, bigger
|-----------------------| overlaps end, bigger
|------------------------------| overlaps entire period
一方、重複しないものはすべて投稿させてください:
|-------------------| compare to this one
|---| ends before
|---| starts after
したがって、単純に比較を次のように減らします。
starts after end
ends before start
次に、重複していないものをすべて見つけ、次に一致しない期間をすべて見つけます。
最後のNOTINLISTの例では、これら2つのルールに一致していることがわかります。
次の期間が範囲内か範囲外かを判断する必要があります。
|-------------|
|-------| equal end with start of comparison period
|-----| equal start with end of comparison period
テーブルにrange_endおよびrange_startという列がある場合、一致するすべての行を取得するための簡単なSQLを次に示します。
SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
OR range_end < @check_period_start)
NOTに注意してください そこで。 2つの単純なルールにより、すべての不一致が検出されるため 行、単純なNOTは、次のように逆にします。一致しない行の1つでない場合は、一致する行の1つである必要があります 。
ここで単純な反転ロジックを適用してNOTを取り除くと、次のようになります。
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start