Php 检查多个课程/会话是否在同一时间范围内

Php 检查多个课程/会话是否在同一时间范围内,php,mysql,Php,Mysql,我正在为班级准备一份内部报名表。我正在开发一个简单的功能,该功能将检查用户是否选择了时间表冲突的课程,例如下午1-2点的课程以及当天下午1-3点的课程 假设我正在使用mysqli并获取用户从带有start和end datetime字段的MySQL表中选择的类,那么比较多个类以查看它们是否冲突的最有效和/或最有效的方法是什么 编辑:下面是一个示例表: ==================================================== | id | start

我正在为班级准备一份内部报名表。我正在开发一个简单的功能,该功能将检查用户是否选择了时间表冲突的课程,例如下午1-2点的课程以及当天下午1-3点的课程


假设我正在使用mysqli并获取用户从带有start和end datetime字段的MySQL表中选择的类,那么比较多个类以查看它们是否冲突的最有效和/或最有效的方法是什么

编辑:下面是一个示例表:

====================================================
|  id  |        start        |         end         | 
====================================================
|  1   | 2012-10-01 08:00:00 | 2012-10-01 08:00:00 |
====================================================
显然,表中还有其他数据,如标题、描述等,但我想我可能只需要上面的数据来进行比较。我将有一个数组,其中包含用户注册的每个类的id


很抱歉,如果这是重复的,我确实搜索过,但没有看到以前询问过的问题。

我不确定此表的主键是什么。我很有信心我的观点对你来说是错误的,但就你的问题而言,这并不重要

-- student_id and class_id are foreign keys, not shown
create table times (
  student_id integer not null,
  class_id integer not null,
  primary key (student_id, class_id), 

  start_time timestamp not null,
  end_time timestamp not null
);
第一个学生在2班和3班之间有重叠

insert into times values
(1, 1, '2012-09-01 08:00', '2012-09-01 08:55'),
(1, 2, '2012-09-01 10:00', '2012-09-01 11:55'),
(1, 3, '2012-09-01 11:45', '2012-09-01 12:45');
第二个学生,没有重叠

insert into times values
(2, 1, '2012-09-01 08:00', '2012-09-01 08:55'),
(2, 2, '2012-09-01 10:00', '2012-09-01 11:55');
第三个学生在1班和2班之间有重叠

insert into times values
(3, 1, '2012-09-01 08:00', '2012-09-01 10:00'),
(3, 2, '2012-09-01 09:55', '2012-09-01 11:55'),
(3, 3, '2012-09-01 12:00', '2012-09-01 12:55');
如果您的平台符合SQL-92,则可以使用重叠运算符。如果任何dbms支持断言,您可以以不可能插入重叠类的方式声明表

select t1.*
from times t1
inner join times t2 on t1.student_id = t2.student_id
       and (t1.class_id <> t2.class_id and t1.start_time <> t2.start_time and t1.end_time <> t2.end_time )
       and (t1.start_time, t1.end_time) overlaps (t2.start_time, t2.end_time);
MySQL似乎不支持这一点,因此您可以使用SQL标准委员会提供的等效定义

select t1.*
from times t1
inner join times t2 on t1.student_id = t2.student_id
       and (t1.class_id <> t2.class_id and t1.start_time <> t2.start_time and t1.end_time <> t2.end_time )
       and (
             (t1.start_time > t2.start_time and not (t1.start_time >= t2.end_time and t1.end_time >= t2.end_time))
             or
             (t2.start_time > t1.start_time and not (t2.start_time >= t1.end_time and t2.end_time >= t1.end_time))
             or
             (t1.start_time = t2.start_time and (t1.end_time <> t2.end_time or t1.end_time = t2.end_time))
       );

我希望连接条件能够给您带来良好的性能,只要您的表被仔细地索引。在您的情况下,您将为单个学生选择行,这应该是非常有选择性的。在我的示例代码中我没有这样做。

使用php的ifWe进行比较的最有效和/或最有效的方法是在没有看到您的表结构和示例数据的情况下回答这个问题。@zerkms您是指带有if语句的循环吗?@Robert Dundon:是的。普通的旧foreach有什么问题吗?1-使用多条目(如单选框)选择类2-使用php将整个课程添加到一个查询中3-使用数组检查计时,当您在数组中设置时间时,您应该为该类创建通知