这看起来应该很容易,但我正撞在墙上。我正在php / mysql中创建一个站点,当用户拉出一周中的某一天时,它将列出按时间块分组的分配,例如8-11,11-14等。
我有一个这样的表设置,其中的字段用于引用包含任务的另一个表。每个整数对应于任务表中的唯一任务。
8-11 11-14 14-17 17-20 20-23
Mon 1 3 4 1 2
Tues 1,3 4 5 6 7
Wed 1,2,3 5 4 8 9
如您所见,有些日子在不同时间有重复任务(例如,在星期一,任务1在8-11和17-20时段执行)。对我来说最令人困惑的是如何设置表或连接多个表以解决具有多个任务的时隙,例如,Wed 8-11班次有三个任务,1,2和3。
我的问题:你能建议最适合这种情况的表结构,以及一个检索给定日期任务的示例查询吗?谢谢。任何帮助是极大的赞赏。
**编辑**这是我想问的问题:看看星期三8-10,我如何从任务表中拉出三个任务?
答案 0 :(得分:1)
http://sqlfiddle.com/#!2/2130b/8
CREATE TABLE work_periods (work_period_id int unsigned, weekday int unsigned, description varchar(50));
CREATE TABLE tasks (task_id int unsigned, description varchar(50));
CREATE TABLE work_period_task_assignments (work_period_id int unsigned, task_id int unsigned);
INSERT INTO work_periods VALUES (1, 1, 'Mon 8-11'), (2, 1, 'Mon 11-14'), (3, 1, 'Mon 14-17');
INSERT INTO tasks VALUES (1, 'Drink Coffee'), (2, 'Make Toast'), (3, 'Do Work');
INSERT INTO work_period_task_assignments VALUES (1, 1), (1, 2), (2,3), (3,3);
SELECT p.description as period, t.description as task FROM work_periods p
INNER JOIN work_period_task_assignments wpta
ON wpta.work_period_id = p.work_period_id
INNER JOIN tasks t
ON wpta.task_id = t.task_id
WHERE p.weekday = 1;
答案 1 :(得分:0)
怎么样:
period (id, desc, start_hour, end_hour), e.g. "8-11"
task (id, desc), e.g. "Task 1")
period_task (period_id, task_id)
因此,对于任务1,你在period_task中有三行。
答案 2 :(得分:0)
对于结构,您可以使用单个分配表:
CREATE TABLE assignments (
assignment_id int AUTO_INCREMENT PRIMARY KEY,
user int,
dt datetime,
assignment_name varchar(50))
然后,您可以使用CASE
对分配数量进行分组。这是一些伪代码:
SELECT timeRange, COUNT(*) AS assignments
FROM
(SELECT
CASE
WHEN HOUR(dt) BETWEEN 8 AND 11 THEN '8-11'
WHEN HOUR(dt) BETWEEN 11 AND 14 THEN '11-14'
WHEN HOUR(dt) BETWEEN 14 AND 17 THEN '14-17'
WHEN HOUR(dt) BETWEEN 17 AND 20 THEN '17-20'
WHEN HOUR(dt) BETWEEN 20 AND 23 THEN '10-23'
END AS timeRange
FROM assignments) t
GROUP BY t.timeRange
您可以根据需要添加根据user
和date
范围进行过滤的条件。
答案 3 :(得分:0)
为了清楚你不能在一个字段中有2个引用,所以我用一个表来保存交叉引用...即daily_tasks,你可以在一天中的每个时间段插入任意数量的项目,唯一的限制是你不能在一个时间段内两次执行相同的任务,但如果删除主键声明,即使这样也可以删除
create table task(
id tinyint unsigned not null auto_increment primary key,
name text not null
) engine InnoDB;
create table timeslot(
id int unsigned not null auto_increment primary key,
date date not null,
time tinyint unsigned not null
) engine InnoDB;
create table daily_tasks(
timeslot int unsigned not null,
task tinyint unsigned not null,
foreign key(timeslot) references timeslot(id) on update cascade on delete cascade,
foreign key(task) references task(id) on update cascade on delete cascade,
primary key(timeslot,task)
) engine InnoDB;
插入一些样本数据
insert into task (name) values ('wake up'), ('wash'), ('eat'), ('drink'), ('go to work'), ('do some work');
insert into timeslot (date, time) values ('2012-09-18', 8), ('2012-09-18', 11), ('2012-09-18', 14), ('2012-09-18', 17), ('2012-09-18', 20);
insert into daily_tasks values (1, 1), (1,3), (1,4), (1,5), (2,6), (3,6), (4,3), (4,4), (4,2);
选择一天的所有任务
select timeslot.time, task.name from timeslot join daily_tasks on daily_tasks.timeslot = timeslot.id join task on task.id = daily_tasks.task where timeslot.date = '2012-09-18' order by timeslot.time asc;
查询结果
+------+--------------+
| time | name |
+------+--------------+
| 8 | wake up |
| 8 | eat |
| 8 | drink |
| 8 | go to work |
| 11 | do some work |
| 14 | do some work |
| 17 | wash |
| 17 | eat |
| 17 | drink |
+------+--------------+
9 rows in set (0.00 sec)
带有连接任务的替代查询
select timeslot.time, group_concat(task.name) from timeslot join daily_tasks on daily_tasks.timeslot = timeslot.id join task on task.id = daily_tasks.task where timeslot.date = '2012-09-18' group by timeslot.time asc;
导致
+------+------------------------------+
| time | group_concat(task.name) |
+------+------------------------------+
| 8 | wake up,eat,drink,go to work |
| 11 | do some work |
| 14 | do some work |
| 17 | wash,eat,drink |
+------+------------------------------+
4 rows in set (0.01 sec)
因为显然所有间隔都是3小时,所以我没有包含任务的结束时间,因为可以通过添加3来计算时间