0

私は予約のためにこのテーブル構造を持っています

|ID|timeBooked         | duration |
|2 |2013-05-09 11:10:00| 30       |
|1 |2013-05-09 14:40:00| 15       |
|AI| timespan          | int(4)   |

duration は、期間を分単位で表します。

だから私が欲しいのは、私がときにこのようにレコードセットを返すことです

2013-05-09 の 00:00:00 から 23:00:00 までの利用可能な時間帯を照会します

|free_from|Free_until| Free |
|00:00:00 |11:10:00  | 1
|11:10:00 |11:40:00  | 0
|11:40:00 |14:40:00  | 1
|14:40:00 |14:55:00  | 0
|14:55:00 |23:00:00  | 1

これはmysqlだけで可能ですか?

4

3 に答える 3

5

わかりました、純粋な MySQL - それらのトリックが好きである限り。表示する期間の「開始」に初期化される変数が必要です。通常は now() のようなものです。

まず、テストデータのみ:

create table bookingEvents 
   (id int not null primary key auto_increment,
    timeBooked datetime, 
    duration int
   );


insert into bookingEvents values (null, '2013-05-13 13:22:00', 15);
insert into bookingEvents values (null, '2013-05-13 15:10:00', 45);
insert into bookingEvents values (null, '2013-05-13 19:55:00', 30);
insert into bookingEvents values (null, '2013-05-14 03:22:00', 15);
insert into bookingEvents values (null, '2013-05-14 08:19:00', 15);

次に、「スライダー」を初期化します。

set @timeSlider='2013-05-10 00:00:00';

次に、次を選択します。

select if (d.name = 'Free', @timeSlider, b.timeBooked) as free_from,
       if (d.name = 'Free', b.timeBooked, @timeSlider := b.timeBooked + interval b.duration minute) as free_until,
       d.name as Free
from (select 1 as place, 'Free' as name union select 2 as place, 'Booked' as name) d 
inner join bookingEvents b 
having free_from < free_until
order by b.timeBooked, d.place;

結果:

+---------------------+---------------------+--------+
| free_from           | free_until          | Free   |
+---------------------+---------------------+--------+
| 2013-05-10 00:00:00 | 2013-05-13 13:22:00 | Free   |
| 2013-05-13 13:22:00 | 2013-05-13 13:37:00 | Booked |
| 2013-05-13 13:37:00 | 2013-05-13 15:10:00 | Free   |
| 2013-05-13 15:10:00 | 2013-05-13 15:55:00 | Booked |
| 2013-05-13 15:55:00 | 2013-05-13 19:55:00 | Free   |
| 2013-05-13 19:55:00 | 2013-05-13 20:25:00 | Booked |
| 2013-05-13 20:25:00 | 2013-05-14 03:22:00 | Free   |
| 2013-05-14 03:22:00 | 2013-05-14 03:37:00 | Booked |
| 2013-05-14 03:37:00 | 2013-05-14 08:19:00 | Free   |
| 2013-05-14 08:19:00 | 2013-05-14 08:34:00 | Booked |
+---------------------+---------------------+--------+

特定の End-Timestamp がある場合は、それを @timeMaximum として事前設定する必要があります

set @timeSlider='2013-05-10 00:00:00';
set @timeMaximum='2013-05-14 08:35:00';


select if (d.name = 'Free', @timeSlider, b.timeBooked) as free_from,
       if (d.name = 'Free', b.timeBooked, @timeSlider := b.timeBooked + interval b.duration minute) as free_until,
       d.name as Free
from (select 1 as place, 'Free' as name union select 2 as place, 'Booked' as name ) as d 
inner join bookingEvents b 
having free_from < free_until
union select @timeSlider as free_from, @timeMaximum as free_until, 'Free' as Free
from (select 1) as d
where @timeSlider < @timeMaximum

order by free_from, free_until
;
于 2013-05-12T15:15:55.080 に答える
1

編集:私の他の答えによって廃止されました。順序付けられたデータを単純に処理する限り、パフォーマンスは良好です。

年:

SQL だけでは、適切な数の行がテーブルにあるとすぐにソリューションが非常に遅くなると思います。

SQL テーブル自体は重複を回避しません。

私はそのようなテーブルを使用します:

CREATE TABLE bookingEvents (id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    event ENUM('start', 'end') NOT NULL,
    bookingId INT(11) NOT NULL,
    eventTime DATETIME NOT NULL,
    index (eventTime)
);

ここで、bookingId は、予約に関する情報を含む追加のテーブルを参照します。

次に、次のようにリストできます。

SELECT event, eventTime 
FROM bookingEvents 
WHERE (date or something)
ORDER BY eventTime;

(予約が重ならない限り) bookingStart と bookingEnd- の時間を交互に取得します。

time1  time2  booked
time2  time3  free
time3  time4  booked
time4  time5  free

すべてのエントリで、開始/終了チェックを使用して、無料および予約済みの試合を簡単に確認できます。

予約の挿入は簡単です

INSERT INTO bookingEvents (event, bookingId, eventTime) 
VALUES ('start', $bookingId, $timeBooked                          ), 
       ('end'  , $bookingId, $timeBooked + interval $length minute)
;
于 2013-05-12T14:04:42.213 に答える
1

自由時間の記録をどのように設定するかはよくわかりませんが、これが正しいアプローチだと思います。

SELECT id, 
    DATE_FORMAT(timeBooked, '%H:%i:%s') AS initial_time, 
    DATE_FORMAT(DATE_ADD(timeBooked, INTERVAL duration MINUTE), '%H:%i:%s') AS final_time, 
    duration
FROM your_table t1
WHERE DATE(timeBooked) = '2013-05-09'
ORDER BY t1.timeBooked ASC;

便利になることを願っています!

于 2013-05-09T11:12:47.940 に答える