预订系统 - 可用表格

时间:2013-01-09 13:06:02

标签: php mysql sql

我已经在这方面工作了几天,我无法理解。 我希望你能帮助我。

我正在开发一个预订系统,我想检查DATE和TIME是否有表格可用。 这就是我的数据库的样子。

enter image description here

我想将可用的表格放入选择下拉菜单中,因此在网站上它只显示可用的表格。

如果我使用以下查询,我可以获得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他的解决方案

首先,回答你的问题

  1. 预订始终在同一天
  2. 预订有固定的时间,总是2个小时。
  3. 我已经将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
    

    此查询输出的结果如下 enter image description here

    如您所见,查询结果显示所有tafels(12)。

    我还将表reserveringen,tafels_regel和tafels导出为.csv(参见下面编辑的.csv)

    编辑2:

    我已经再次编辑了我的查询,它适用于一部分。 这是查询(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
    

2 个答案:

答案 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

这可能仍需要一些调整,如:

  1. 不能正确处理跨越天数的预订(即,一天盯着,另一天结束)。 (但也许你不需要这个)
  2. 表格将显示为10月10日12:30,当它实际上从2012年1月10日12:45保留时(可能没有人对表格感兴趣)至少X分钟 - 1小时是免费的吗? - 他们想要的开始时间之后?)。
  3. 编辑(回答下面的OP评论):

    查看您的数据,我可以看到您在2013年1月12日19:00至21:00之间保留了Tafel 1。我可以看出为什么你没有得到预期的结果(即不应该显示Tafel 1,因为它不是免费的):

    1. 您在查询中使用的日期是2012年而不是2013年。(这可能源自我的示例,我使用的是2012年)
    2. 我设计的例子是使用单个时间点&#34;所需的时间&#34;。我的想法是'#34;理想的时间&#34;将是一个点(例如19:30) - 因此预订开始(例如)19:00和结束20:00将使该期望时间不可用。因为&#34;所需的时间&#34;您正在使用的是一个范围(19:00到21:00),它恰好与预订的范围完全相同,&#34;&lt;&# 34;和&#34;&gt;&#34;在查询中未能将此预订作为与期望时间&#34;的冲突。 (&#34;&lt; =&#34;和&#34;&gt; =&#34;相反会修复此问题。)
    3. 但是,由于您说所有预订都是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)

好吧,我真的不了解你的数据库结构。但为了让你走上正轨:

  1. 您可以简单地查询所有表格
  2. 您从结果集中排除了反向表
  3. 类似的东西:

    SELECT tafelnaam FROM Tafels WHERE tafelnr NOT IN (SELECT tafelnr *OF YOUR RESEVED TABLES*)