Предположим, что у нас есть эта таблица.
CREATE TABLE `appointments` (
`idappointments` int(11) NOT NULL AUTO_INCREMENT,
`timeStart` time DEFAULT NULL,
`timeEnd` time DEFAULT NULL,
PRIMARY KEY (`idappointments`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8$$
предположение
Предположим, что диапазон между timeStart и timeEnd can not существует снова... Я имею в виду, что если мы пересекаем все диапазоны в таблице, результат будет ПУСТОЙ, 0, null. Назначение can not cooexist с другим.
Итак, что я хочу сделать, это предложение времени, если желаемое время занято... Предложение до и предложение после желаемого времени....
Так мне было интересно, а не писать код, чтобы сделать это, если я могу написать SQL-запрос, чтобы найти ближайшие пустые диапазоны......
Ex.. timeStart - NEAREST_TO_TIMESTART_TIMEEND > '10 минут ', а 10 минут - продолжительность
MySQL не имеет рекурсивной функциональности, поэтому вам остается использовать трюк таблицы NUMBERS -
Создайте таблицу, содержащую только инкрементные числа - легко сделать с помощью auto_increment:
DROP TABLE IF EXISTS `example`.`numbers`;
CREATE TABLE `example`.`numbers` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Заполните таблицу, используя:
INSERT INTO NUMBERS
(id)
VALUES
(NULL)
... для количества значений, которые вам нужны.
Используйте DATE_ADD, чтобы создать список дат, увеличивая дни на основе значения NUMBERS.id. Замените "2010-01-01" и "2010-01-02" на соответствующие даты начала и окончания (но используйте тот же формат, YYYY-MM-DD HH: MM: SS) -
SELECT x.dt
FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
FROM numbers n
WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
LEFT JOIN на таблицу данных, основанную на части datetime.
SELECT x.dt
FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
FROM numbers n
WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
WHERE a.idappoinment IS NULL
AND x.dt > @your_minimum_datetime
ORDER BY x.dt
LIMIT 1
SELECT x.dt,
CASE
WHEN a.idappoinment IS NULL THEN 'available'
ELSE 'booked'
END AS isbooked
FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE)) AS dt
FROM numbers n
WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) * 15 MINUTE) <= '2010-01-02' ) x
LEFT JOIN APPOINTMENTS a ON x.dt BETWEEN a.timestart AND a.timeend
ORDER BY x.dt
Простые даты могут быть сгенерированы на основе числа, как в приведенном выше примере. Это также означает использование одной таблицы, например, для каждого типа данных.
NULL
и0
разные :)