1

问题看起来像这样:

我有一个带有 classes 的表,每个都有 start_time 和 end_time (存储为 INT - 分钟,例如 120 - 2:00、130 - 2:10),我需要做的是通过用户类选择并过滤其余部分检索不与选定对象冲突的类。有人能帮忙吗 ?也许有些线索?

示例行:

id start end
1   0    100
2   50   150
3   160  200
4   50   150
5   50   100
6   200  300

如果我选择了 id=1 那么它应该返回第 3,6 行(它涵盖了 50 到 100 之间的 2,4,5,因此不可能同时参加这两个课程)

如果我选择了 id=2,6 那么它应该返回第 3 行

如果我选择了 id=2 那么它应该返回第 3,6 行

如果我选择了 id=6 那么它应该返回第 1,2,3,4,5 行

如果我选择了 id=3 那么它应该返回第 1,2 行

4

2 回答 2

3

除了假设您所说的一个表之外,几乎没有其他任何东西,您将需要一个自联接:

SELECT rest.*
FROM classes AS chosen
RIGHT JOIN classes AS rest
    ON rest.start_time NOT BETWEEN chosen.start_time AND chosen.end_time
    AND rest.end_time NOT BETWEEN chosen.start_time AND chosen.end_time
WHERE chosen.ClassID = '4'

我将表格别名为所选班级的“选择”,以及班级列表的其余部分的“休息”。这将返回与 WHERE 子句中提到的所选类不重叠的所有“其余”类。

于 2013-05-31T21:35:06.533 回答
3

这为一个给定的 id 提供了重叠的 id:

select id from classes c
inner join classes noc on noc.id = <given id>
where c.start > noc.end or c.end < noc.start
;

编辑:

据我现在理解的扩展示例,您希望将任意的 id 子集作为输入,并希望拥有不与其中任何一个重叠的所有 id。我们试试看:

select c.* 
from classes c 
left join classes noc on noc.id in (<idlist>) 
     and noc.start < c.end 
     and noc.end > c.start 
where noc.id is null;

根据“重叠”的含义,“<”和“>”可能是“<=”和“>=”。

您听起来不像在寻找子类,但我认为您会在 set-djungle 中找到自己的方式!;-)

您的示例“selected id=3”给了我 1,2,4,5,6,因为 3 没有人重叠。

解释:

  • 上课
  • 查找与给定类重叠的类
  • 并且只显示那些没有发现重叠类的类。

noc代表“不允许的课程” 。如果找到该类,则与您的给定集合存在重叠。

于 2013-05-31T21:43:18.560 回答