0

这似乎应该很容易,但我正在用头撞墙。我在 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 时段执行)。而最让我困惑的是如何设置表或连接多个表以解决具有多个任务的时间段,例如,周三 8-11 班有三个任务,1、2 和 3。

我的问题:您能否建议最适合此的表结构,以及检索给定日期任务的示例查询?谢谢你。任何帮助是极大的赞赏。

** 编辑 ** 这就是我要问的问题:看看星期三 8-10,我怎样才能从任务表中拉出三个任务?

4

4 回答 4

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;
于 2012-09-18T00:58:46.103 回答
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 中有三行。

于 2012-09-18T00:31:10.653 回答
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

您可以根据需要添加过滤条件userdate范围。

于 2012-09-18T00:34:14.833 回答
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 添加到时间来计算

于 2012-09-18T00:48:40.650 回答