如何在time
的两个范围之间进行查询,而不包括这两个范围本身?
我有一个使用whereBetween
查询时间的工作代码,但我遇到了一个问题,因为我只想获得这两个时间范围 * 之间 * 的记录,而不包括它们本身。
我的schedules
表中有以下行:
+----------+------------------+----------------+-------------+
| id | start_time | end_time | user_id |
+----------+------------------+----------------+-------------+
| 1 | 06:45:00 | 07:45:00 | 1 |
| 2 | 10:30:00 | 11:30:00 | 1 |
+----------+------------------+----------------+-------------+
我正在执行的步骤:
1.向schedules
表中添加新记录。
1.假设我的新记录包含07:45:00的start_time
和08:45:00的end_time
。
1.使用下面的代码检查要添加的记录之间是否有任何记录。
我用来检查$startTime
和$endTime
之间是否有一行的代码。
$userId = 1;
$startTime = Carbon::parse('07:45')->format('H:i:s');
$endTime = Carbon::parse('08:45')->format('H:i:s');
$checkScheduleIfExists = Schedule::where('user_id', $userId)
->where(function ($query) use ($startTime, $endTime) {
$query->whereBetween('start_time', [
$startTime, $endTime
])
->orWhereBetween('end_time', [
$startTime, $endTime
]);
})
->first();
dd($checkScheduleIfExists);
// this returns the row id 1, 06:45:00 - 07:45:00
上面代码的问题是,它在schedules
表的end_time
中找到$startTime
,即07:45:00,并返回该行,如果在start_time
中找到$endTime
,情况也是如此。
如果$startTime
(07:45:00)所占用的空间小于schedules
表中存在的end_time
,例如7:40:00,我希望只返回一行(以知道记录存在)。
1条答案
按热度按时间gmxoilav1#
这是一个标准的问题,简单的答案是:给定一个从
S
开始到E
结束的时间间隔,用于获取重叠时间间隔的DB查询应如下所示:说明:
为了形象化(并更好地记住)这一点,想象两个不重叠的区间,我们称它们为
S1-E1
和S2-E2
。如果它们不重叠,那就意味着其中一个是第一个,另一个是第二个,我们不知道哪个是哪个,所以要么是
E1 <= S2
(第一个在第二个开始之前结束),要么是E2 <= S1
(第二个在第一个开始之前结束)。既然我们已经把它写下来了,那么我们就很容易得到两个区间DO以某种方式重叠的所有情况--只要在这个条件前面加上一个
not
(否定)。该条件考虑了间隔如何可能重叠的每种可能方式,包括一个间隔完全包括另一个间隔,或者间隔部分重叠。我们可以通过打开括号来进一步简化这个表达式,在这种情况下,我们得到
E1 > S2 and E2 > S1
。