Shahkalpesh 回答了这个问题:
我认为你需要一个 OR。
SELECT * FROM appts
WHERE (timeStart >='$timeStart'
OR timeEnd <='$timeEnd')
AND dayappt='$boatdate'
我发表了一条我认为这是错误的评论,并给出了一对反例:
这是完全错误的——@ShaneD 是正确的。例如,这将选择 05:00 到 06:00 之间的预订,因为实际结束时间小于您询问的任何结束时间。出于同样的原因,它还将从 18:00 开始收取租金。
在回应我的评论时,Shahkalpesh 要求:
您能否发布带有预期输出的数据和输入参数的单独回复?
很公平 - 是的。略微编辑,问题说:
逻辑是可以预订租船
- 从早上 7 点到下午 1 点,或
- 从上午 9 点到下午 1 点,或
- 从上午 9 点到下午 5 点。
如果在该范围内有约会,它应该返回约会,但事实证明它是不一致的。如果我选择早上 9 点到下午 1 点,...
足够的背景。我们可以忽略约会的日期,只考虑时间。我假设有一种简单的方法可以将记录的时间限制为 hh:mm 格式;并非所有 DBMS 实际上都提供了这一点,但处理 hh:mm:ss 的扩展是微不足道的。
Appointments
Row timeStart timeEnd Note
1 07:00 13:00 First valid range
2 09:00 13:00 Second valid range
3 09:00 17:00 Third valid range
4 14:00 17:00 First plausibly valid range
5 05:00 06:00 First probably invalid range
6 18:00 22:30 Second probably invalid range
给定搜索重叠范围 09:00 - 13:00 的约会,Shahkalpesh 的(简化)查询变为:
SELECT * FROM Appointments
WHERE (timeStart >= '09:00' OR timeEnd <= '13:00')
这将返回所有六行数据。但是,只有第 1、2、3 行与 09:00 - 13:00 时间段重叠。如果第 1、2 和 3 行是唯一有效的代表任命值,那么 Shahkalpesh 的查询会产生正确的答案。但是,如果允许第 4 行(我认为这似乎是有效的),则不应返回它。同样,不应返回第 5 行和第 6 行(如果存在)。[实际上,假设 timeStart <= timeEnd
对于表中的所有行(并且没有 NULL 值会搞砸),我们可以看到 Shahkalpesh 的查询将返回 09:00-13:00 查询的任何数据行,因为无论是开始时间行的时间大于 09:00 或结束时间小于 13:00 或两者兼有。这相当于 1 = 1
WHERE 子句中的写作或任何其他重言式。]
如果我们考虑 ShaneD 的查询(简化):
SELECT * FROM Appointments
WHERE timeStart <= '13:00' AND timeEnd >= '09:00'
我们看到它也选择了第 1、2 和 3 行,但它拒绝了第 4 行(因为 timeStart > '13:00')、第 5 行(因为 timeEnd < '09:00')和第 6 行(因为 timeStart > '13: 00')。这个表达式是一个典型示例,说明如何选择“重叠”的行,将“满足”和“满足”(例如,参见“艾伦的区间代数”)计算为重叠。更改 '>=' 和 '<=' 会更改计为重叠的间隔集。