首页  >  问答  >  正文

php - mysql多表查询

有这么两张表,大致描述一下。

表一:
课程和学生的关系表r
sid cid
1 | 1
1 | 2

学号为1 的选了cid 为1 ,和2 的课程

表二:
课程的具体时间表d
cid day start end
1 | 2 | 14 | 16
2 | 2 | 13 | 15

课程cid 为1 在周2 14点-16点

另外还有,学生表s,sid sname。 课程表c,cid cname

这里从r和d可以看出1 这个学生选了两门有冲突的课程。怎么用sql 语句查询出这种冲突的记录呢?
也就是一个学生 sid 选择了时间冲突的 cid 的记录呢?

用连接可以查询出 sid 对应的cid 和对应的时间 ,然后怎么判断课程是否在时间上冲突呢?

附:这个问题的场景是一个题目集上看到的,我也同意选课的时候做判断

滿天的星座滿天的星座2703 天前737

全部回复(3)我来回复

  • 阿神

    阿神2017-05-25 15:10:10

    这个很好解决:

    1. 查出这个学生报名的所有的课程

    2. 检测这些课程的时间上是否冲突

      • 看是不是在同一天,同一天的就比对开始和结束时间有没有冲突,交集

      • 不是同一天的就没问题

    补充:

    不过这个问题,应该是在报名时就要规避的,就不允许产生冲突。

    报名时检测他所报名的课程时间与已经报名的课程有没有时间冲突,有冲突就不允许报名。

    至于在时间轴上面比较两个时间段是否有冲突其实也很好算的

    A - B, C - D

    A - C - B 或者 A - D - B

    C - A - D 或者 C - B - D

    四种情况下会有交集,说明时间冲突了。

    回复
    0
  • 巴扎黑

    巴扎黑2017-05-25 15:10:10

    其实,我觉得,这种有冲突的课程,在学生选课的时候就应该做判断,不应该让他加到数据库当中

    方法:
    每次在学生选课的时候,先用选择的这个课程的时间,去查询数据库里是否已经存在当前冲突的数据

    例如:
    假如,sid = 1 的学生已经选择了cid = 1 的课程,然后在选择 cid = 2 的课程时,sql如下:

    select * from r left join d on r.cid = d.cid where d.day = 2 and (d.start between 13 and 15 or d.end between 13 and 15)

    这样查出来的是在当天,该时间段内是否有选中的课程存在,这样,如果有结果,则表示你选的这个课程和你报名的课程时间上有冲突

    回复
    0
  • 習慣沉默

    習慣沉默2017-05-25 15:10:10

    这种问题可以自连接解决。

    select tmp1.sid,tmp1.cid,tmp2.cid 
        from 
            (select a.sid,a.cid,b.day,b.start,b.end from tbl1 a inner join tbl2 on a.cid=b.cid) tmp1 
            left join  (select a.sid,a.cid,b.day,b.start,b.end from tbl1 a inner join tbl2 on a.cid=b.cid) tmp2 
                on tmp1.sid = tmp2.sid and tmp1.cid<>tmp2.cid and tmp1.day = tmp2.day
        where (tmp1.start > tmp2.start and tmp1.start < tmp2.end) 
            or (tmp1.end > tmp2.end and tmp1.end < tmp2.end)

    回复
    0
  • 取消回复