Arhn - архитектура программирования

Использование 2 таблиц для результатов

Я делаю систему бронирования для школьного проекта, но теперь я застрял.

У меня есть страница, где вы можете проверить, есть ли свободные номера для определенной категории и даты.

Я знаю, что вам нужно сделать внутреннее соединение. Я использовал Google, но я понятия не имею, как это сделать.

Это в моей базе данных отелей:

У меня есть таблица номеров:

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>

Я надеюсь, что кто-то может помочь мне!

заранее спасибо!

-- редактировать

Теперь, когда я смотрю на таблицу бронирования, не лучше ли хранить там и категорию?

03.10.2014

Ответы:


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 в целом) является то, что синтаксис языка пытается максимально походить на английскую письменность. Объяснение запроса: мы SELECT roomNR из тех rooms, которых нет в результате SELECT roomNR FROM reservation (или, проще говоря, в таблице reservation).

Синтаксис и дополнительную информацию о подзапросах см. на http://dev.mysql.com/doc/refman/5.1/en/subqueries.html.

Часть 2: Реализация PHP

Чтобы сделать еще один шаг вперед и следовать вашей бизнес-логике, можно сказать следующее:

Выберите те категории, в которых есть номера (хотя бы один номер), не указанные в бронировании

И здесь вы можете реализовать INNER JOIN. Переводя нашу проблему в MySQL - при условии, что у вас есть поля id и name для catagory - мы имеем:

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

Если я не ошибаюсь, этот запрос должен запрашивать данное имя категории, если есть хотя бы одна комната с идентификатором этой категории, не указанная в бронировании. Пожалуйста, проверьте, работает ли это для вас, я не в той среде, где я мог бы проверить это прямо сейчас.

ИЗМЕНИТЬ: 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.

03.10.2014
  • Спасибо за информацию. Я использовал подзапрос, и теперь я получаю номера, которых нет в таблице резервирования. Но мне нужно, чтобы комната отображалась в списке, когда комната свободна в указанную дату от и до, которая была передана пользователем. 03.10.2014
  • Я немного дополнил свой ответ. Как видите, теперь мы применяем предложение WHERE к подзапросу, ограничивая проверяемые резервирования. 03.10.2014
  • Кроме того, вам необходимо убедиться, что вводимые пользователями date или datetime определенно совместимы и сопоставимы с вашим форматом хранения. 03.10.2014

  • 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'
    
    03.10.2014
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..