当前位置:  开发笔记 > 后端 > 正文

如何比较一行中的重叠值?

如何解决《如何比较一行中的重叠值?》经验,为你挑选了2个好方法。

我似乎有这个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语句,包括那些重叠的?



1> Jonathan Lef..:

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 ")重叠的行.更改'> ='和'<='会更改计为重叠的间隔集.



2> Shane Delmor..:

正确的检查将如下所示:

SELECT * FROM appts 
WHERE timeStart <='$timeEnd' 
AND timeEnd >='$timeStart' 
AND dayappt='$boatdate'

已经给出了其他很好的解释,但我会继续更新它,并用我自己想象的方式替代解释.大多数人都在寻找每个可能的重叠,考虑到两个时间段,他们试图考虑开始和结束的每个组合,这可以使约会重叠.我认为这是因为两个时间段不重叠,由于某些原因对我来说更容易.

说我正在检查的时间段是今天,我想找到今天不重叠的任何时间段.实际上只有两种情况,即时间段在今天之后开始(PeriodStart> EndOfToday)或时间段在今天之前结束(PeriodEnd

鉴于我们有一个不重叠的简单测试:
(PeriodStart> EndOfToday)OR(PeriodEnd

快速翻转你有一个简单的重叠测试:
(PeriodStart <= EndOfToday)AND(PeriodEnd> = StartOfToday)

-Shane

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有