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 根据日期时间部分加入您的数据表。
这将向您显示第一个可用插槽:
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
为什么是数字,而不是日期?
简单 - 可以根据数字生成日期,就像我提供的示例一样。这也意味着使用一个表,而不是每个数据类型一个表。