我有一个表,可以按小时为教师存储可用的约会,每个教师每天可以自由添加无限的时段(只要插槽不重叠)。示例简化结构:
CREATE TABLE time_slots (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
teacher_id mediumint(8) unsigned NOT NULL,
slot bigint(20) unsigned NOT NULL DEFAULT '0',
);
slot 列存储广告位的时间戳。
如何为每位教师显示所有可用的第一个可用日期? 注意:显示给定日期的所有时段,并且不能为同一位教师显示超过一天的时间。
PS:使用日期时间只是为了让事情更具可读性。
+----+------------+------------------+
| id | teacher_id | slot |
+----+------------+------------------+
| 1 | 1 | 2013-04-10 08:00 |
| 2 | 1 | 2013-04-10 09:00 |
| 3 | 1 | 2013-04-10 09:30 |
| 4 | 1 | 2013-04-11 08:00 |
| 5 | 1 | 2013-04-11 09:00 |
| 6 | 1 | 2013-04-11 10:30 |
| 7 | 2 | 2013-04-12 07:00 |
| 8 | 2 | 2013-04-12 09:00 |
| 9 | 2 | 2013-04-14 08:00 |
+----+------------+------------------+
假设搜索时间为: 2013-04-10 08:30 ,则返回的结果必须为:
+----+------------+------------------+
| id | teacher_id | slot |
+----+------------+------------------+
| 2 | 1 | 2013-04-10 09:00 |
| 3 | 1 | 2013-04-10 09:30 |
| 7 | 2 | 2013-04-12 07:00 |
| 8 | 2 | 2013-04-12 09:00 |
+----+------------+------------------+
我很难接受查询,我刚刚接受了这个基本查询,但它没有假设只获得第一天,当然它不会返回给定日期的所有可用插槽。每个教师只返回1个插槽:
SELECT id, teacher_id, FROM_UNIXTIME(slot)
FROM time_slots
WHERE slot >= [Actual timestamp]
GROUP BY DATE(FROM_UNIXTIME(slot))
ORDER BY slot, teacher_id ASC
注意:我在这里只是为了调试而使用FROM_UNIXTIME,当然我稍后会优化索引等。
答案 0 :(得分:2)
首先,您需要查询以获得每位教师最近的天,因为每位教师都会有所不同。一些假的SQL在这里这样做:
SELECT
MIN(DATE(slot)) as closestDay,
teacher_id
FROM time_slots
WHERE slot >= NOW()
GROUP BY teacher_id
然后接受该查询并使用结果显示每天的所有可用插槽
SELECT
id,
time_slots.teacher_id,
FROM_UNIXTIMESTAMP(slot)
FROM time_slots
JOIN (
SELECT
MIN(DATE(slot)) as closestDay,
teacher_id
FROM time_slots
WHERE slot >= NOW()
GROUP BY teacher_id
) a
ON a.teacher_id = time_slots.teacher_id
AND DATE(time_slots.slot) = closestDay
WHERE time_slots.slot >= NOW()
显然没有经过测试,但它应该给你一般的想法。
答案 1 :(得分:1)
无需加入:
drop table if exists time_slots;
CREATE TABLE time_slots (
id int(10) unsigned NOT NULL AUTO_INCREMENT primary key,
teacher_id mediumint(8) unsigned NOT NULL,
slot datetime
);
insert into time_slots values
('1','1','2013-04-10 08:00'),
('2','1','2013-04-10 09:00'),
('3','1','2013-04-10 09:30'),
('4','1','2013-04-11 08:00'),
('5','1','2013-04-11 09:00'),
('6','1','2013-04-11 10:30'),
('7','2','2013-04-12 07:00'),
('8','2','2013-04-12 09:00'),
('9','2','2013-04-14 08:00');
select * from time_slots
where (teacher_id, date(slot)) in
(select teacher_id, date(min(slot)) from time_slots where slot >= '2013-04-10 08:30' group by teacher_id)
having slot >= '2013-04-10 08:30'
;