Это может показаться типичным вопросом, но я не могу найти ответ на эту проблему.
У меня есть таблица бронирования:
book_id | arrive_date | depart_date 1 2015-07-20 2015-07-22 2 2015-07-22 2015-07-23 3 2015-07-19 2015-07-20
Вы увидите, что я показал, что дата отправления может быть датой прибытия и наоборот
Перед добавлением даты я проверяю, что диапазон дат не будет конфликтовать с датами в таблице, важно разрешить дату отправления быть датой прибытия, поскольку человек будет уходить, чтобы разрешить это, когда я проверяю даты в в таблице I ADD дате date_date и SUBTRACT в день из date_date, используя этот SQL:
Select * From booking Where booking.unit_id = 58 And ( DATE_ADD(booking.from_date, INTERVAL 1 DAY) BETWEEN '2015-07-23' AND '2015-07-24' OR DATE_SUB(booking.to_date, INTERVAL 1 DAY) BETWEEN '2015-07-23' AND '2015-07-24' OR '2015-07-23' BETWEEN DATE_ADD(booking.from_date, INTERVAL 1 DAY) AND DATE_SUB(booking.to_date, INTERVAL 1 DAY)) Limit 1
Когда я добавил первое свидание, никаких проблем … то же самое со вторым и третьим, это сработало, потому что первый диапазон дат я ввел день между (20 и 22). Затем я пытаюсь добавить «2015-07-23» и «2015-07-24», который проверяется с использованием вышеуказанного SQL, который, очевидно, возвращает результат. Мне нужен способ, который позволит принять эти даты, поскольку 23-й – это de_date.
Любая помощь будет оценена
Я должен также упомянуть, что у меня также есть таблица, в которой хранятся заблокированные даты «booking_prev», поэтому аналогичный запрос также будет использоваться для проверки дат в блоке до тех, которые указаны в таблице бронирования, прежде чем они будут введены.
Рассмотрим следующее …
DROP TABLE IF EXISTS my_table; CREATE TABLE my_table (book_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,arrive_date DATE NOT NULL ,depart_date DATE NOT NULL ); INSERT INTO my_table VALUES (1,'2015-07-20','2015-07-22'), (2,'2015-07-22','2015-07-23'), (3,'2015-07-19','2015-07-20'); SELECT * FROM my_table; +---------+-------------+-------------+ | book_id | arrive_date | depart_date | +---------+-------------+-------------+ | 1 | 2015-07-20 | 2015-07-22 | | 2 | 2015-07-22 | 2015-07-23 | | 3 | 2015-07-19 | 2015-07-20 | +---------+-------------+-------------+
Таким образом, SELECT могут выглядеть так …
SELECT '2015-07-22','2015-07-24' FROM (SELECT 1) x LEFT JOIN my_table y ON y.arrive_date < '2015-07-24' AND y.depart_date > '2015-07-22' WHERE y.book_id IS NULL LIMIT 1; Empty set (0.00 sec) SELECT '2015-07-23','2015-07-24' FROM (SELECT 1) x LEFT JOIN my_table y ON y.arrive_date < '2015-07-24' AND y.depart_date > '2015-07-23' WHERE y.book_id IS NULL LIMIT 1; +------------+------------+ | 2015-07-23 | 2015-07-24 | +------------+------------+ | 2015-07-23 | 2015-07-24 | +------------+------------+
… но сначала вам не нужно их проверять. Я преднамеренно написал SELECTs таким образом, что проверка может произойти как часть INSERT …
INSERT INTO my_table (arrive_date,depart_date) SELECT '2015-07-23','2015-07-24' FROM (SELECT 1) x LEFT JOIN my_table y ON y.arrive_date < '2015-07-24' AND y.depart_date > '2015-07-23' WHERE y.book_id IS NULL LIMIT 1; SELECT * FROM my_table; +---------+-------------+-------------+ | book_id | arrive_date | depart_date | +---------+-------------+-------------+ | 1 | 2015-07-20 | 2015-07-22 | | 2 | 2015-07-22 | 2015-07-23 | | 3 | 2015-07-19 | 2015-07-20 | | 4 | 2015-07-23 | 2015-07-24 | +---------+-------------+-------------+
Хорошо, хотя принятый ответ очень хорошо работает, мне все же нужно проверить, что запись даты действительна, главным образом потому, что я проверял даты в основной таблице бронирования, прежде чем я добавил ее в таблицу, которая блокировала даты. В любом случае, следуя SQL, похоже, все необходимые проверки:
Select * From booking Where booking.unit_id = 58 And ((booking.arrive_date < '2015-07-23' And booking.depart_date >= '2015-07-24') OR (booking.arrive_date <= '2015-07-23' And booking.depart_date > '2015-07-24') OR (booking.arrive_date >= '2015-07-23' And booking.depart_date <= '2015-07-24') OR ('2015-07-23' > booking.arrive_date And '2015-07-23' < booking.depart_date ) OR ('2015-07-24' > booking.arrive_date And '2015-07-24' < booking.depart_date )) Limit 1
Немного разочаровался в том, что я был отмечен решением, которое я дал, так как он проверял значения в таблице, что было одним из моих требований, хотя это не так эффективно для реальной вставки.
Перемещение Я расширил принятый ответ, добавив больше полей, которые я использую, на основе таблицы для хранения запрещенных дат бронирования:
INSERT INTO booking_prevent (unit_id, from_date, to_date, note) SELECT 58, '2015-07-28', '2015-07-29', 'My Note' FROM (SELECT 1) x LEFT JOIN booking_prevent y ON y.from_date < '2015-07-29' И y.to_date> '2015-07-28' И y.unit_id = 58 WHERE y.booking_prevent_id IS NULL LIMIT 1
Это работает очень хорошо, но я немного зациклился на том, как я могу сделать обновление для записи, но только внести изменения … снова, если это действительно так. Это то, что у меня есть, это удар в темноте:
UPDATE booking_prevent SET (unit_id, from_date, to_date, note) SELECT 58, '2015-07-20', '2015-07-26', 'Обновленное примечание' FROM (SELECT 1) x LEFT JOIN booking_prevent y ON y.from_date < '2015-07-26' И y.to_date> '2015-07-20' И y.unit_id = 58 WHERE y.booking_prevent_id IS NULL WHERE booking_prevent_id = 466 LIMIT 1
Любые указатели будут оценены.