2016-04-06 4 views
2

Ich habe eine Tabelle mit Reservierungen drin.Berechnen Sie freie Zeit Slots von Reservierung Tabelle

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

Reservierungen sind nur zwischen 07:00 und 19:00 Uhr möglich. Was ich tun möchte, ist, den freien Zeitschlitz zwischen, vor und nach den Reservierungen immer für das aktuelle Datum zu bekommen/zu berechnen.

Ist dies möglich auf DB-Layer, vielleicht mit einer Stored Procedures? Kann mir jemand bei diesem Punkt helfen?

+0

anycode Sie müde? zeige –

Antwort

2

unter Beispieldaten:

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 

folgende Abfrage ergibt alle freien Zeitschlitze:

;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 

Ergebnis

+---------------------+---------------------+ 
|  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 | 
+---------------------+---------------------+ 

Wenn Sie SQL älter als 2012 verwenden werden Sie nicht LEAD und LAG haben, so dass Sie unter Abfrage stattdessen verwenden können, Ihre ID als Primärschlüssel unter der Annahme

;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 

** Bitte „Mark als Antwort“, wenn Dieser Beitrag beantwortet die Frage

+0

Hallo Flicker, Iam mit SQL Server 2008. LAG und LEAD funktioniert nicht auf 2008. Wie kann ich diese zwei Zeilen neu schreiben? – Bashud

+0

Hummm, es macht es etwas kompliziert. Haben Sie einen ganzzahligen Primärschlüssel in Ihrer Tabelle? – FLICKER

+0

Ja, ich habe einen Integer Primärschlüssel in meiner Tabelle – Bashud

1

funktioniert dies für die Daten, die Sie

bereitgestellt
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

Ich habe deine Antwort versucht. Ich bekomme ein Ergebnis, das ich nicht verstehen kann. würdest du bitte das ergebnis in deine antwort aufnehmen und erklären? – FLICKER

+0

hat meine Antwort bearbeitet. – Kostya

Verwandte Themen