• Hi

    I thought that I would try something out of left field with this as a matter of interest. I use Geometry a lot and thought it would be interesting to use it for something different.

    Anyway here's what I came up with ... it will not be as quick as others though

    if object_id('tempdb.dbo.#RoomDates', 'U') is not null

    drop table #RoomDates

    create table #RoomDates (

    HotelId int not null

    ,RoomTypeId int not null

    ,StartDate date not null

    ,EndDate date not null

    ,dateGraph Geometry

    ,constraint [PK_tempRoom] primary key clustered (

    HotelId

    ,RoomTypeId

    ,StartDate

    ) with (

    pad_index = off

    ,statistics_norecompute = off

    ,ignore_dup_key = off

    ,allow_row_locks = on

    ,allow_page_locks = on

    ) on [PRIMARY]

    ) on [PRIMARY]

    insert #RoomDates ( HotelId

    ,RoomTypeId

    ,StartDate

    ,EndDate)

    values (1,1,'2012-01-01', '2012-02-01'),

    (1,1,'2012-01-10', '2012-02-05'),

    (1,1,'2012-02-4', '2012-03-01'),

    (1,1,'2012-03-10', '2012-03-13'),

    (1,1,'2012-03-11', '2012-03-20'),

    (2,1,'2012-01-01', '2012-02-01'),

    (2,1,'2012-01-10', '2012-01-20'),

    (3,1,'2012-01-01', '2012-02-01'),

    (1,1,'2012-02-27', '2012-03-05'),

    (3,1,'2012-03-10', '2012-03-20')

    update #RoomDates

    set dateGraph = Geometry::STGeomFromText('LINESTRING (' +

    cast(cast(cast(startdate as datetime) as int) as varchar) + ' ' + cast(roomtypeid + hotelid as varchar) + ', ' +

    cast(cast(cast(enddate as datetime) as int) as varchar) + ' ' + cast(roomtypeid + hotelid as varchar) + ')'

    ,0)

    ;with

    overlap as (

    select a.hotelid, a.roomtypeid, a.startdate, a.enddate, b.enddate maxenddate

    from #RoomDates a

    left join #RoomDates b on

    a.hotelid = b.hotelid and

    a.roomtypeid = b.roomtypeid and

    a.startdate < b.startdate and

    a.dategraph.STIntersects(b.dategraph) = 1

    ),

    grouper as (

    select row_number() over (order by hotelid, roomtypeid, startdate) groupid,

    hotelid, roomtypeid, startdate, enddate

    from overlap a

    where maxenddate is null

    union all

    select g.groupid, g.hotelid, g.roomtypeid, o.startdate, o.enddate

    from grouper g

    inner join overlap o on g.enddate = o.maxenddate and g.hotelid = o.hotelid and g.roomtypeid = o.hotelid

    ),

    merger as (

    select hotelid, roomtypeid, min(startdate) startdate, max(enddate) enddate

    from grouper

    group by groupid, hotelid, roomtypeid

    )

    select * from merger