这是一个经典问题,如果你颠倒逻辑,它实际上更容易。
让我给你举个例子。
我将在这里发布一段时期,以及以某种方式重叠的其他时期的所有不同变化。
|-------------------| 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
然后你会找到所有不重叠的,然后你会找到所有不匹配的时期。
对于您最后的 NOT IN LIST 示例,您可以看到它符合这两个规则。
您需要确定以下时段是在您的范围内还是在您的范围之外:
|-------------|
|-------| 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。由于这两个简单的规则找到了所有不匹配的行,一个简单的 NOT 会反转它说:如果它不是不匹配的行之一,它必须是匹配的行之一。
在这里应用简单的反转逻辑来摆脱 NOT,你最终会得到:
SELECT *
FROM periods
WHERE range_start <= @check_period_end
AND range_end >= @check_period_start