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シフトには3つのタスク、1、2、および3があります。

私の質問:これに最適なテーブル構造と、特定の日のタスクを取得するためのクエリの例を提案できますか?ありがとうございました。どんな助けでも大歓迎です。

**編集**これが私が尋ねようとしていることです:水8-10を見て、どうすればタスクテーブルから3つのタスクを引き出すことができますか?

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

構造の場合、単一の割り当てテーブルを使用できます。

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範囲指定する基準を追加します。

于 2012-09-18T00:34:14.833 に答える
0

明確にするために、1つのフィールドに2つの参照を含めることはできないため、相互参照を保持するためにテーブルを使用します...つまり、daily_tasksでは、1日のタイムスロットごとに必要な数のアイテムを挿入できます。制限は、1つのタイムスロットで同じタスクを2回実行することはできないということですが、主キー宣言を削除すれば、それでも削除できます。

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);

1日のすべてのタスクを選択するには

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 に答える
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 には 3 つの行があります。

于 2012-09-18T00:31:10.653 に答える