php - 使用 2 个表格获取结果

标签 php mysql sql inner-join

我正在为学校项目制作预订系统,但现在卡住了。

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

我知道您必须进行内部联接。我用过谷歌,但我不知道如何去做。

这是在我的酒店数据库中:

我有一张房间表:

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>

我希望有人能帮助我!

提前致谢!

-- 编辑

既然我正在查看预订表,那么将目录也存储在那里不是更好吗?

最佳答案

第 1 部分:未预订的房间

首先将任务简化为简单的单词是一个好的做法:

Select those rooms, which are not referred to in any reservation entry, and are from a given category.

您实际上在这里需要的不是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)的一个幸运特性是,语言语法尽可能地类似于英语书面语言。 查询解释:我们SELECT那些房间roomNRSELECT roomNR FROM reservation 结果(或者,简单地说,reservation 表)。

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

第 2 部分:PHP 实现

为了更进一步,并遵循您的业务逻辑,可以说以下内容:

Select those categories, that have rooms (at least one room) not referenced in reservation

这是您可以实现 INNER JOIN 的地方。将我们的问题转化为 MySQL - 假设你有 catagoryidname 字段 - 我们有:

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 部分:按开始和结束日期过滤结果

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

Select those categories, that have at least one room not referenced in reservations. Reservations that are outside our time scope (example: reservation has already expired by the time the next user begins their own reservation) can be ignored, since their rooms are free, so they no longer limit our possibilities.

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

$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 子句的限制元素。

关于php - 使用 2 个表格获取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26182279/

相关文章:

php - 我应该为我的案例将 com-sep 数据存储在数据库中吗?

php - 用于登录信息和关键任务信息的独立数据库?

php - 这个 PHP MySQL 查询有什么问题?

php - PDO 不从 mysql 查询返回结果

mysql - 如何在MySQL中进行多个组计数

sql - 如何获得最年长的人?

mysql - 如何编写条件 A 或 B 为零,但在 MYSQL 中不是两者都为零?

php - 存储非英文字符,得到 '?????' - MySQL 字符集问题

php - 按用户评论过滤 - SQL 参数数量必须在 0 到 65535 之间

limit - 所有具有 limit1 的表的 MySQL 转储