2016-04-06 3 views
2

予約済みのテーブルがあります。空き時間の計算予約テーブルからのスロット

('2016-04-06 09:00:00', '2016-04-06 09:15:00'), 
('2016-04-06 11:00:00', '2016-04-06 11:30:00'), 
('2016-04-06 12:00:00', '2016-04-06 12:45:00'), 
('2016-04-06 16:30:00', '2016-04-06 16:45:00'), 

07:00から19:00までの間にのみ予約できます。 私がやりたいことは、予約の前後にある空き時間スロットを取得/計算することです。

これは、おそらくストアドプロシージャでDBレイヤーで実行できますか?誰かがその点で私を助けることができますか?

+0

あなたは疲れていますか?表示 –

答えて

2

を提供されたデータのために働く:、

select * into #t from (
select 1 ID, '2016-04-06 09:00:00' r_start , '2016-04-06 09:15:00' r_end union 
select 2, '2016-04-06 11:00:00', '2016-04-06 11:30:00'union 
select 3, '2016-04-06 12:00:00', '2016-04-06 12:45:00'union 
select 4, '2016-04-06 16:30:00', '2016-04-06 16:45:00') AS bookdata 

クエリ以下のすべての自由な時間スロットを結果:

;with booked as (
    select r_start, r_end 
    , LAG(r_end) over (order by r_end) PrevBook 
    , LEAD(r_start) over (order by r_start) NextBook 
    from #t 
) 
select IsNull(PrevBook, '2016-04-06 07:00:00') AS FreeStart, r_start AS FreeEnd 
from booked 
union 
select r_end, IsNull(NextBook, '2016-04-06 19:00:00') 
from booked 

結果

+---------------------+---------------------+ 
|  FreeStart  |  FreeEnd  | 
+---------------------+---------------------+ 
| 2016-04-06 07:00:00 | 2016-04-06 09:00:00 | 
| 2016-04-06 09:15:00 | 2016-04-06 11:00:00 | 
| 2016-04-06 11:30:00 | 2016-04-06 12:00:00 | 
| 2016-04-06 12:45:00 | 2016-04-06 16:30:00 | 
| 2016-04-06 16:45:00 | 2016-04-06 19:00:00 | 
+---------------------+---------------------+ 

あなたは2012年よりも古いSQLを使用している場合は、主キー

;with booked as (
    select r_start, r_end 
    , (select top 1 r_end from #t where ID < tbl.ID order by ID desc) PrevBook 
    , (select top 1 r_start from #t where ID > tbl.ID order by ID) NextBook 
    from #t tbl 
) 
select IsNull(PrevBook, '2016-04-06 07:00:00') AS FreeStart, r_start AS FreeEnd 
from booked 
union 
select r_end, IsNull(NextBook, '2016-04-06 19:00:00') 
from booked 

として、あなたの持っているIDを想定すると、代わりにクエリの下に使用することができますので、あなたはLEADとLAGを持っていません**してください「回答としてマーク」の場合この投稿は質問に回答しました

+0

こんにちはFlicker、iamはSQL Server 2008を使用しています。LAGとLEADは2008で動作しません。どうすれば2行書き換えることができますか? – Bashud

+0

ハムム、それは少し複雑になります。あなたのテーブルに整数の主キーがありますか? – FLICKER

+0

はい、私のテーブルに整数プライマリキーがあります – Bashud

1

これはあなたがサンプルデータの下に使用

select * into #t from (

select '2016-04-06 09:00:00'r_start , '2016-04-06 09:15:00'r_end union all 
select'2016-04-06 11:00:00', '2016-04-06 11:30:00'union all 
select'2016-04-06 12:00:00', '2016-04-06 12:45:00'union all 
select'2016-04-06 16:30:00', '2016-04-06 16:45:00') x 

--returns duration between 1st reservation and the next 
select 
datediff(MINUTE,x.r_end,y.r_start)/60 'hours' 
,datediff(MINUTE,x.r_end,y.r_start) - datediff(MINUTE,x.r_end,y.r_start)/60 * 60 'minutes' 
,x.r_start 
,x.r_end 
from 
(select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) x 
left join (select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) y 
on x.rowid = y.rowid - 1 


--returns unreserved dates 
select 
x.r_end available_from 
,y.r_start available_to 
from 
(select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) x 
left join (select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) y 
on x.rowid = y.rowid - 1 
+0

あなたの答えを試しました。私は理解できない結果を得る。答えに結果を含めて説明してください。 – FLICKER

+0

私の答えを編集しました。 – Kostya