【问题标题】:Room Availability check SQLite Query房间可用性检查 SQLite 查询
【发布时间】:2016-08-12 07:39:16
【问题描述】:

我是新手,但我正在努力掌握 Web 开发的艺术,但由于 SQLite 查询,我在学习过程中惨遭失败。

这是我的数据库设计:

我想寻找可用的房间,但我的查询没有给我正确的结果!!!

我用虚假预订手动填充 SQLite 数据库,然后针对已预订的完全相同的日期运行各种查询,但预订的房间一直显示为可用,因为它在查询日期之前和之后确实可用!但查询日期是重要日期!这就是为什么预订的房间根本不应该出现!但我无法提出正确的查询!

我的假预订:

2016 年 5 月 10 日至 2016 年 5 月 13 日预订房间号 101 的单人间

这是我迄今为止“最好的”查询:

SELECT * FROM Rooms NATURAL LEFT JOIN Booking WHERE RoomType='SR' AND
Checkout IS NULL OR Arrival <= '2016-05-10' AND Checkout <= '2016-05-10'
AND RoomType='SR' OR Arrival >= '2016-05-13' AND Checkout >= '2016-05-13'
AND RoomType='SR' OR Arrival <> '2016-05-10' AND Checkout <> '2016-05-13'
AND RoomType='SR';

SR 是 RoomType(单人房)

当我运行查询时,101 号房间需要从结果集中完全消失!但是 101 不断出现!

Arrival 和 Checkout 字段在 SQLite DB 中属于 DATE 类型。

你们能帮帮我吗?

另外,我是否在 PHP 中正确执行 PRAGMA 外键? Booking 表中的 CustomerID 和 RoomNumber 是外键。

<?php
$db = new PDO('sqlite:gshotel.db');
$db->exec('PRAGMA foreign_keys = ON;');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
prepare...
execute...
?>

非常感谢

【问题讨论】:

  • 使用括号。很确定您的 WHERE 子句应该是 (A and B and C) 或 (D and E and F) or... 也简化它,您不需要检查 4 次以确保 RoomType='SR ',你只需要检查一次。

标签: php sql database sqlite


【解决方案1】:

确保检查您拥有的 4 个案例,并确保所有 4 个案例的 RoomType = 'SR'。只是简化您的查询并确保分组对于条件是正确的。

SELECT * FROM Rooms 
NATURAL LEFT JOIN Booking 
WHERE Checkout IS NULL 
OR (Arrival <= '2016-05-10' AND Checkout <= '2016-05-10')
OR (Arrival >= '2016-05-13' AND Checkout >= '2016-05-13')
OR (Arrival <> '2016-05-10' AND Checkout <> '2016-05-13')
AND RoomType='SR';

【讨论】:

  • 嗨!我刚刚运行了您的版本,但仍然没有成功!预订的房间还在显示:(
  • 括号还是太少了。
【解决方案2】:

好吧,我花了一整天的时间,但我终于设法破解它!

SELECT * FROM Rooms NATURAL LEFT JOIN Booking WHERE
   (
      Checkout IS NULL 
      AND RoomType='SR'
   ) 
   OR (
      (
         '2016-05-10' NOT BETWEEN Arrival and Checkout
      ) 
      AND (
         '2016-05-13' NOT BETWEEN Arrival and Checkout
      ) 
      AND (
         Arrival NOT BETWEEN '2016-05-10' and '2016-05-13'
      ) 
      AND (
         Checkout NOT BETWEEN '2016-05-10' and '2016-05-13'
      ) 
      AND (
         RoomType='SR'
      )   
      AND (
         RoomNumber NOT IN (
            SELECT RoomNumber from Rooms NATURAL LEFT JOIN Booking WHERE
               RoomType = 'SR' 
               AND (
                  Arrival BETWEEN '2016-05-10' and '2016-05-13'
                  OR Checkout BETWEEN '2016-05-10' and '2016-05-13'
                  OR '2016-05-10' BETWEEN Arrival and Checkout
                  OR '2016-05-13' BETWEEN Arrival and Checkout
                  )
         )
      )
   );

我很确定这个查询可以进一步简化,但现在,我很高兴它可以工作!我对它进行了广泛的测试!

【讨论】:

    【解决方案3】:

    这是一篇旧帖子,但我最近发现了它,因为我从这篇帖子中获得了一些想法,所以我想分享我遇到的解决方案,并且工作正常。

    SELECT RoomNumber From Rooms WHERE RoomNumber NOT IN
            (SELECT RoomNumber FROM Booking WHERE (('2016-05-10' BETWEEN 
            Arrival AND CheckOut) OR ('2016-05-13' BETWEEN Arrival AND 
            CheckOut) OR (CheckIn BETWEEN '2016-05-10' AND '2016-05-13') OR 
            (CheckOut BETWEEN '2016-05-10' AND '2016-05-13'))) AND 
            Roomtype = "SR"
    

    这是另一个使用左连接的查询,一开始就建立了,但这种方式很实用,至少从我的角度来看不是。

    SELECT * From Rooms LEFT JOIN Booking ON Rooms.RoomNumber = 
            Booking.RoomNumber WHERE Rooms.NumeroHAB NOT IN
            (SELECT Booking.RoomNumber FROM Booking WHERE (('2016-05-10' BETWEEN 
            Arrival AND CheckOut) OR ('2016-05-13' BETWEEN Arrival AND 
            CheckOut) OR (Arrival BETWEEN '2016-05-10' AND '2016-05-13') OR 
            (CheckOut BETWEEN '2016-05-10' AND '2016-05-13'))) AND 
            RoomType = "SR" ORDER BY Rooms.RoomNumber ASC
    

    【讨论】:

      猜你喜欢
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 2012-06-03
      • 2013-01-17
      • 1970-01-01
      相关资源
      最近更新 更多