使用 MYSQL php yii2 检查开始时间和结束时间是否部分重叠?
Check if start time and end time partially overlapping using MYSQL php yii2?
伙计们
我一直在试图弄清楚如何检查两次之间的部分重叠。
基本上,我的时间保存在这样的数据库中:-
Batch::find()->alias('batch')->joinWith([
'batchTeachers as teacher',
'attendanceDates as attendanceDates',
'batchTiming as batchTiming'
])->where([
'OR', [
'IN',
'teacher.teacher_id',
$teacher_id
],
[
'IN',
'batch.teacher_id',
$teacher_id
]
])->andWhere([
'attendanceDates.date' => $date
])->andWhere([
'OR',
[
'AND',
[
'>=',
'batchTiming.start_time',
$calenderStartTime
],
[
'<=',
'batchTiming.end_time',
$calenderEndTime
]
], [
'AND', [
'<=',
'attendanceDates.start_time',
$calenderEndTime
], [
'>=',
'attendanceDates.end_time',
$calenderEndTime
]
]
])->exists()
上述查询的原始 SQL 是:
SELECT `batch`.* FROM `tbl_batch` `batch` LEFT JOIN `tbl_attendance_batch_teacher` `teacher` ON `batch`.`id` = `teacher`.`batch_id` LEFT JOIN `tbl_attendance_date` `attendanceDates` ON `batch`.`id` = `attendanceDates`.`batch_id` LEFT JOIN `tbl_batch_timing` `batchTiming` ON `batch`.`id` = `batchTiming`.`batch_id` WHERE ((`teacher`.`teacher_id`=1294) OR (`batch`.`teacher_id`=1294)) AND (`attendanceDates`.`date`='2021-01-06') AND (((`batchTiming`.`start_time` >= '08:00:00') AND (`batchTiming`.`end_time` <= '09:00:00')) OR ((`attendanceDates`.`start_time` <= '09:00:00') AND (`attendanceDates`.`end_time` >= '09:00:00'))) ORDER BY `date`
我的问题是如果用户在上午 9 点到 11 点之间有一批
如果他从早上 9 点到 11 点很忙,那么 满 重叠(红色)
如果他从上午 9 点到 10 点很忙,那么 部分 重叠(蓝色)
您需要在 SQL SELECT
中使用 CASE WHEN 语句
SELECT
` batch `.*,
CASE
WHEN ( ` batchTiming `.` start_time ` >= '08:00:00' AND ` batchTiming `.` end_time ` <= '09:00:00' ) THEN 1 -- partial overlap
WHEN ( ` attendanceDates `.` start_time ` <= '09:00:00' AND ` attendanceDates `.` end_time ` >= '09:00:00' ) THEN 2 -- full overlap
ELSE 0 -- no overlap
END as overlap_value
FROM
参考here
进一步将其转换为 Active Query 添加 select 子句,如下所示...
Batch::find()
->alias('batch')
->select([ 'T.*', 'othrTable.*', ' CASE STATEMENT HERE as overlap_value'])
->joinWith( [...
并在批处理模型中添加 $overlap_value 作为 属性。
伙计们
我一直在试图弄清楚如何检查两次之间的部分重叠。
基本上,我的时间保存在这样的数据库中:-
Batch::find()->alias('batch')->joinWith([
'batchTeachers as teacher',
'attendanceDates as attendanceDates',
'batchTiming as batchTiming'
])->where([
'OR', [
'IN',
'teacher.teacher_id',
$teacher_id
],
[
'IN',
'batch.teacher_id',
$teacher_id
]
])->andWhere([
'attendanceDates.date' => $date
])->andWhere([
'OR',
[
'AND',
[
'>=',
'batchTiming.start_time',
$calenderStartTime
],
[
'<=',
'batchTiming.end_time',
$calenderEndTime
]
], [
'AND', [
'<=',
'attendanceDates.start_time',
$calenderEndTime
], [
'>=',
'attendanceDates.end_time',
$calenderEndTime
]
]
])->exists()
上述查询的原始 SQL 是:
SELECT `batch`.* FROM `tbl_batch` `batch` LEFT JOIN `tbl_attendance_batch_teacher` `teacher` ON `batch`.`id` = `teacher`.`batch_id` LEFT JOIN `tbl_attendance_date` `attendanceDates` ON `batch`.`id` = `attendanceDates`.`batch_id` LEFT JOIN `tbl_batch_timing` `batchTiming` ON `batch`.`id` = `batchTiming`.`batch_id` WHERE ((`teacher`.`teacher_id`=1294) OR (`batch`.`teacher_id`=1294)) AND (`attendanceDates`.`date`='2021-01-06') AND (((`batchTiming`.`start_time` >= '08:00:00') AND (`batchTiming`.`end_time` <= '09:00:00')) OR ((`attendanceDates`.`start_time` <= '09:00:00') AND (`attendanceDates`.`end_time` >= '09:00:00'))) ORDER BY `date`
我的问题是如果用户在上午 9 点到 11 点之间有一批
如果他从早上 9 点到 11 点很忙,那么 满 重叠(红色)
如果他从上午 9 点到 10 点很忙,那么 部分 重叠(蓝色)
您需要在 SQL SELECT
中使用 CASE WHEN 语句SELECT
` batch `.*,
CASE
WHEN ( ` batchTiming `.` start_time ` >= '08:00:00' AND ` batchTiming `.` end_time ` <= '09:00:00' ) THEN 1 -- partial overlap
WHEN ( ` attendanceDates `.` start_time ` <= '09:00:00' AND ` attendanceDates `.` end_time ` >= '09:00:00' ) THEN 2 -- full overlap
ELSE 0 -- no overlap
END as overlap_value
FROM
参考here
进一步将其转换为 Active Query 添加 select 子句,如下所示...
Batch::find()
->alias('batch')
->select([ 'T.*', 'othrTable.*', ' CASE STATEMENT HERE as overlap_value'])
->joinWith( [...
并在批处理模型中添加 $overlap_value 作为 属性。