4

教師が利用できる予定を時間単位で保存するテーブルがあり、教師ごとに 1 日あたり無制限のスロットを自由に追加できます (スロットが重複しない限り)。単純化された構造の例:

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

スロット列には、スロットのタイムスタンプが格納されます。

すべての教師について、最も近い利用可能な日のすべての利用可能なスロットを表示するにはどうすればよいですか? 注意: 特定の日のすべての時間帯を表示し、同じ教師に対して複数の日を表示することはできません。

サンプルデータ:

PS: 読みやすくするためだけに datetime を使用します。

+----+------------+------------------+
| 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. ID 1 は 4 月 10 日からすでに 08:00 を過ぎているため、表示しないでください。
  2. id 4、5、6 は表示しないでください。教師 = 1 に最も近い利用可能なスロットが id 2 と 3 であることが判明したためです。
  3. 教師 = 2 の場合、利用可能な最も近いスロットは 7 と 8 であるため、ID 9 を表示しないでください。別の日に戻らないでください。

私が試したこと

クエリを実行するのに苦労しています。この基本的なクエリを実行したところですが、利用可能な最初の日だけを取得することは想定されておらず、もちろん、特定の日に利用可能なすべてのスロットが返されるわけではありません。教師ごとに 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 を使用しています。もちろん、後でインデックスなどを最適化します。

4

2 に答える 2

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'
;
于 2013-04-10T19:33:04.483 に答える