我已经在这方面工作了几天,我无法理解。 我希望你能帮助我。
我正在开发一个预订系统,我想检查DATE和TIME是否有表格可用。 这就是我的数据库的样子。
我想将可用的表格放入选择下拉菜单中,因此在网站上它只显示可用的表格。
如果我使用以下查询,我可以获得reserverd表
SELECT res.reserveringsnr, datum, begintijd, eindtijd, tafr.tafelnr FROM reserveringen AS res
INNER JOIN tafels_regel AS tafr
ON res.reserveringsnr = tafr.reserveringsnr
WHERE (res.datum = "2013/12/18" AND (res.begintijd BETWEEN "12:00:00" and "14:00:00"))
所以查询放出了reserverd表,但这里是我被困的地方。 我不知道如何在DATE和TIME检查某个表是否被重新保存。
(注意:日期和时间将由变量填写,但对于我仅使用文本的示例)
首先,回答你的问题
我已经将sebt的查询编辑为我的值:
SELECT t.* FROM
tafels t
LEFT JOIN
(SELECT tafelnr FROM
tafels_regel tf
INNER JOIN
reserveringen res
ON tf.reserveringsnr=res.reserveringsnr
WHERE
res.datum="2012/01/12" AND
res.begintijd<"19:00:00" AND
res.eindtijd>"21:00:00"
)
ReservationsAtThisTime
ON t.tafelnr=ReservationsAtThisTime.tafelnr
WHERE ReservationsAtThisTime.tafelnr IS NULL
此查询输出的结果如下
如您所见,查询结果显示所有tafels(12)。
我还将表reserveringen,tafels_regel和tafels导出为.csv(参见下面编辑的.csv)
我已经再次编辑了我的查询,它适用于一部分。 这是查询(Screenshot)
SELECT t.* FROM
tafels t
LEFT JOIN
(SELECT tafelnr FROM
tafels_regel tf
INNER JOIN
reserveringen res
ON tf.reserveringsnr=res.reserveringsnr
WHERE
res.datum="2013/01/12" AND
res.begintijd <= "19:00:00" AND
res.eindtijd >= "21:00:00"
)
ReservationsAtThisTime
ON t.tafelnr=ReservationsAtThisTime.tafelnr
WHERE ReservationsAtThisTime.tafelnr IS NULL
2013/01/12有2项保留。 (Download编辑.csv)
预订1:从19:00到21:00在tafel 1
预订2:tafel 11和tafel 12的20:00至22:00
当我运行上面的查询时,唯一没有显示的tafel是tafel 1,因为tafel 1从19:00到21:00被重新保存。但是,从20:00到22:00,tafel 11和12也被保留了。
正如您在查询结果中看到的那样,只保留了tafel 1。 但是当我从19:00到21:00进行另一次保护并且我正在检查可用的tafels时,那么tafel 11和tafel 12仍然显示。
tafel将在19:00免费,这是正确的,但由于我们总是坐2个小时,我们不能坐在那里。
再次感谢@sebt提供的意见,希望你能帮助我进一步解决这个问题!
感谢所有帮助,这是最后的查询
SELECT t.* FROM
tafels t
LEFT JOIN
(SELECT tafelnr FROM
tafels_regel tf
INNER JOIN
reserveringen res
ON tf.reserveringsnr=res.reserveringsnr
WHERE
res.datum="2013/01/12" AND
res.eindtijd > "19:00:00" AND
res.begintijd < "21:00:00"
)
ReservationsAtThisTime
ON t.tafelnr=ReservationsAtThisTime.tafelnr
WHERE ReservationsAtThisTime.tafelnr IS NULL
答案 0 :(得分:1)
我认为你的问题有点令人困惑,因为SQL&#34; Tables&#34;之间存在歧义。 (数据库表),以及数据库中的一个对象,这是(我猜)一个餐馆桌,名为&#34; tafel&#34;用荷兰语?
(让我们继续打电话给他们&#34; tafel&#34;,因为这样可以消除歧义)
要仅选择无保留的tafels,您可以将所有tafels连接到[期望时间]当前的预约集,并且仅返回不在等待的tafels。有这样的保留:
SELECT t.* FROM
Tafels t
LEFT JOIN
(SELECT tafelnr FROM
Tafels_regel tf
INNER JOIN
Reserveringen res
ON tf.reserveringnr=res.reserveringnr
WHERE
res.Datum=[desired date] AND
res.begintijd<[desired time] AND
res.eindtijd>[desired time]
) ReservationsAtThisTime
ON t.tafelnr=ReservationsAtThisTIme.tafelnr
WHERE ReservationsAtThisTime.tafelNR IS NULL
这可能仍需要一些调整,如:
编辑(回答下面的OP评论):
查看您的数据,我可以看到您在2013年1月12日19:00至21:00之间保留了Tafel 1。我可以看出为什么你没有得到预期的结果(即不应该显示Tafel 1,因为它不是免费的):
但是,由于您说所有预订都是2小时,因此更容易指定一个冲突的预订&#34;只需使用所需的开始时间,如下所示:a&#34;冲突的预订&#34;是在所需的开始时间后2小时内占用任何时间的那个:
一个。 res.Datum = [所需日期];和 湾res.eindtijd&gt; [期望的开始时间];和 C。 res.begintijd&lt; [期望的开始时间+2小时]
我不完全确定代码如何工作2小时(我的专业是MS-SQL而不是MySQL,日期/时间操作可能有点特定于SQL的版本)
EDIT2(回答OP重新引发的问题):
为了帮助说清楚,我将定义这些术语:
现有预订:已存在于数据库中。有TafelNr,Date,StartTime(begintijd)和EndTime(eindtijd)
建议的预订:用户想要的预订 - 当然,它还没有存在于数据库中,或者拥有TafelNr。有Date,StartTime,EndTime。
(您已经使用StartTime和EndTime为建议的预订实施了查询。我建议使用StartTime,然后使用[StartTime + 2小时]。但是您使用的这些方式中的哪一种并不是&#39 ; t对我们所谈论的问题有所作为)
你是对的,如果查询工作正常,则不应显示第11和第12条。您在19:00至21:00之间预订的预订应在20:00至22:00之间与现有预订发生冲突。但是,正如您所发现的,这种冲突未被发现,因为它应该是。
原因是您的开始/结束时间比较略有错误。您编码的方式:
res.begintijd <= [Proposed Start time] AND
res.eindtijd >= [Proposed End time]
只有在跨度拟议预订时才会发现现有预订存在冲突:完全填写相同的时间,或在提议的预订之前和/或之后延长。
想象两个预订(现有的和建议的),比如乐高的平行块沿着相邻的线滑动是有帮助的。他们根本不能接触(好);或者只是联系(一个人的结局=另一个人的开始:好,没有冲突 - 只是!);或者一方的结束可以延伸到另一方的开始(冲突);或者一个人可以跨越另一个,从同一时间开始或在另一个之前,并在与另一个或更晚的同时结束(冲突)。
这是我多年前使用预订系统解决的一个伎俩。找到冲突的正确比较(如我上面的编辑):
ExistingBookingEndTime>ProposedBookingStartTime AND
ExistingBOokingStartTime<ProposedBookingEndTime
或使用您的对象名称:
res.eindtijd>"19:00:00" AND
res.begintijd<"21:00:00"
这一开始可能没有意义,但如果你想一下乐高积木,它就会有意义。
注意:
1。我正在使用&lt;和&gt;,不是&lt; =和&gt; =,因为我认为预订可以直接相互延伸并且只要它们不重叠就可以触摸&#34;
2。在比较日期和时间时要小心 - 它可以给出奇怪的结果,只需比较它们就好像它们是数字或字符串一样。我不知道MySQL如何处理这个问题,但这是我一直小心/偏执的事情。
答案 1 :(得分:0)
好吧,我真的不了解你的数据库结构。但为了让你走上正轨:
类似的东西:
SELECT tafelnaam FROM Tafels WHERE tafelnr NOT IN (SELECT tafelnr *OF YOUR RESEVED TABLES*)