房间可用性检查SQLite查询

时间:2016-04-19 21:42:57

标签: php sql database sqlite

我是一个新手,但我正在努力掌握Web开发的艺术,并且由于SQLite查询而在我的学习过程中失败了。

这是我的数据库设计:

enter image description here

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

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

我的假预订:

2016-05-10至2016-05-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号房间需要完全从Resultset中消失!但101不断出现!

ArrivalCheckout字段在SQLite DB中的类型为DATE

你能帮帮我吗?

而且,我在PHP中正确地做PRAGMA外键事吗?预订表中的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...
?>

非常感谢

3 个答案:

答案 0 :(得分:0)

请务必检查您的4个案例,并确保RoomType =&#39; SR&#39;对于所有4个人。只需简化查询并确保条件化的分组正确。

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';

答案 1 :(得分:0)

好的,我花了整整一天但我终于成功破解了它!

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
                  )
         )
      )
   );

我很确定这个查询可以进一步简化,但就目前而言,我很高兴它有效!我对它进行了广泛的测试!

答案 2 :(得分:0)

这是一篇旧文章,但我最近发现了它,并且由于我从这篇文章中汲取了一些想法,所以我想分享我遇到的解决方案,并且只是简而言之。

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