我似乎有这个SQL查询的问题:
SELECT * FROM appts WHERE timeStart >='$timeStart' AND timeEnd <='$timeEnd' AND dayappt='$boatdate'
时间格式为军事时间.物流是租船可以在早上7点至下午1点至下午1点或上午9点至下午5点预订.如果在该范围内有appt,它应该返回appts,但事实证明它不一致.如果我选择上午9点直到下午1点,它将忽略从早上7点开始的应用程序,即使它在上午9点到下午1点重叠.如果我选择9到5,它将返回任何内容,即使它应该在早上7点到下午1点.如何创建包含从timeStart到timeEnd的整个范围的SQL语句,包括那些重叠的?
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' ).这个表达式是一个典型的例子,说明如何选择"重叠",计数"满足"和"满足"(例如,参见" Allen's Interval Algebra ")重叠的行.更改'> ='和'<='会更改计为重叠的间隔集.
正确的检查将如下所示:
SELECT * FROM appts WHERE timeStart <='$timeEnd' AND timeEnd >='$timeStart' AND dayappt='$boatdate'
已经给出了其他很好的解释,但我会继续更新它,并用我自己想象的方式替代解释.大多数人都在寻找每个可能的重叠,考虑到两个时间段,他们试图考虑开始和结束的每个组合,这可以使约会重叠.我认为这是因为两个时间段不重叠,由于某些原因对我来说更容易.
说我正在检查的时间段是今天,我想找到今天不重叠的任何时间段.实际上只有两种情况,即时间段在今天之后开始(PeriodStart> EndOfToday)或时间段在今天之前结束(PeriodEnd 鉴于我们有一个不重叠的简单测试: 快速翻转你有一个简单的重叠测试: -Shane
(PeriodStart> EndOfToday)OR(PeriodEnd
(PeriodStart <= EndOfToday)AND(PeriodEnd> = StartOfToday)