【问题标题】:Using 2 tables for results使用 2 个表格获取结果
【发布时间】:2014-11-28 17:00:31
【问题描述】:

我正在为一个学校项目进行预订系统,但现在我卡住了。

我有一个页面,您可以在其中检查特定房间类别和日期的房间是否可用

我知道您必须进行内部连接。我用过谷歌,但我不知道怎么做。

这在我的酒店数据库中:

我有一张客房桌:

TABLE `rooms` (
  `roomNR` int(11) NOT NULL,
  `catagory` varchar(11) DEFAULT NULL,
  `picLocation` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`roomNR`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我有一个预订表,其中存储了所有预订。

TABLE `reservation` (
  `reservationID` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userID` int(11) NOT NULL,
  `roomNR` int(11) NOT NULL,
  `start` date NOT NULL,
  `end` date NOT NULL,
  `price` float NOT NULL,
  PRIMARY KEY (`reservationID`),
  UNIQUE KEY `userID` (`userID`),
  UNIQUE KEY `roomNR` (`roomNR`),
  CONSTRAINT `reservation_ibfk_1` FOREIGN KEY (`roomNR`) REFERENCES `rooms` (`roomNR`),
  CONSTRAINT `reservation_ibfk_2` FOREIGN KEY (`userID`) REFERENCES `users` (`userID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

这是我使用的表格:

<form action="" method="GET">
<div>
    <label for="StartDate">From</label>
    <input type="input" name="startDate" id="startDate" readonly=""> <label for="EndDate">Till</label> <input readonly="" type="input" name="endDate" id="endDate">
        <label for="Catagory">Catagory:</label>
        <select name="Catagory" id="Catagory">
            <?php 

            $catagorys = DB::Getinstance()->query('SELECT * FROM catagory');

            if ($catagorys->count()) {
                foreach($catagorys->results() as $catagory){?>
                <option value="<?php echo $catagory->name; ?>"><?php echo $catagory->name; ?></option>

                <?php }
            }

            ?>
        </select> <input type="submit" value="get available rooms" class="btn btn-default">
        </div>



    </form>

希望有人能帮帮我!

提前谢谢你!

--编辑

现在我正在查看预订表,将类别也存储在其中不是更好吗?

【问题讨论】:

    标签: php mysql sql inner-join


    【解决方案1】:

    第 1 部分:未预订的房间

    首先将任务简化为简单的单词是一种好习惯

    选择那些没有在任何预订条目中提及的房间,它们来自给定的类别。

    您实际上需要的不是INNER JOIN。至少不是这部分任务。 INNER JOIN 稍后将用于与catagory“链接”。

    在此处使用INNER JOIN 可以轻松选择预订的房间:SELECT rooms.roomNR FROM rooms INNER JOIN reservation ON rooms.roomNR=reservation.roomNR WHERE catagory=$category_id。当然,您可以在 PHP 中处理这些信息并使用它来非常有效地选择表中的剩余行,但是还有更好的方法。

    您需要一个子查询

    SELECT roomNR FROM `rooms` WHERE catagory=$category_id AND roomNR NOT IN (SELECT roomNR FROM `reservation`)
    

    这是 MySQL(或 SQL,一般来说)的一个幸运特性,语言语法尽可能地类似于英语书面语言。 查询解释:我们SELECTrooms 中的roomsSELECT roomNR FROM reservation 结果中(或者,简单地说,reservation 表)。

    有关子查询的语法和更多信息,请查看http://dev.mysql.com/doc/refman/5.1/en/subqueries.html

    第 2 部分:PHP 实现

    要更进一步,并遵循您的业务逻辑,可以这样说:

    选择那些有房间(至少一个房间)未在预订中引用的类别

    您可以在这里实现INNER JOIN。将我们的问题转换为 MySQL - 假设您有 idname 字段用于 catagory - 我们有:

    SELECT catagory.name FROM catagory INNER JOIN rooms ON catagory.id=rooms.catagory WHERE rooms.roomNR NOT IN (SELECT roomNR FROM reservation);
    

    如果我没记错的话,如果至少有一个房间的类别 ID 未在预订中引用,则此查询应该查询给定的类别名称。请回来看看这是否适合你,我现在不在一个可以测试它的环境中。

    编辑: DISTINCT 关键字

    如果查询以任何方式多次返回给定的catagory,请使用DISTINCT 关键字:

    SELECT DISTINCT catagory.name FROM catagory ...
    

    第 3 部分:按开始和结束日期过滤结果

    要按开始和结束日期进行过滤,我们会遇到以下问题:

    选择那些至少有一个房间没有被引用的类别 预订。超出我们时间范围的预订(例如: 到下一个用户开始他们的预订时,预订已经过期 自己的预订)可以忽略,因为他们的房间是免费的,所以他们 不再限制我们的可能性。

    下一个查询中使用的变量是:

    $start_date = $_POST['startDate'];
    $end_date = $_POST['endDate'];
    

    把它变成SQL:

    SELECT catagory.name FROM catagory INNER JOIN rooms ON catagory.id=rooms.catagory WHERE rooms.roomNR NOT IN (SELECT roomNR FROM reservation WHERE end<$start_date OR start>$end_date);
    

    如您所见,我们在子查询中使用了逆逻辑。当我们检查给定房间是否已经预订时(已经在reservation 中),我们会忽略那些不符合时间标准的预订:它在下一次预订开始之前已经结束,或者在下一次预订结束之前开始。因此它不会成为NOT IN 子句的限制元素。

    【讨论】:

    • 感谢您提供的信息。我已经使用了子查询,现在我得到了不在预订表中的房间。但是,当房间在用户指定的开始日期和截止日期可用时,我需要房间显示在列表中。
    • 我增加了我的答案。如您所见,我们现在将WHERE 子句应用于子查询,限制了我们要检查的保留。
    • 另外,您需要确保用户输入的datedatetime 肯定是兼容的,并且与您的存储格式可比
    【解决方案2】:

    不,您也不需要在预订表上保存类别,这将是多余的。

    要获得针对该类别的预订,以及有关预订的房间信息,您需要这样的查询:

    SELECT rooms.roomNR, rooms.category, rooms.picLocation,
    res.reservationID, res.userID, res.start, res.end, res.price
    FROM rooms 
    INNER JOIN reservations res ON rooms.roomNR = res.roomNR
    WHERE rooms.category = 'your_category_selection'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 2016-03-05
      相关资源
      最近更新 更多