Reputation: 47
I have a table name RoomInventory
that has data like below
Date (Date) RoomsAvailable (int)
1-Jul-2015 30
2-Jul-2015 30
3-Jul-2015 30
5-Jul-2015 28
6-Jul-2015 28
7-Jul-2015 28
8-Jul-2015 30
9-Jul-2015 30
10-Jul-2015 26
11-Jul-2015 28
12-Jul-2015 28
The result which I want is like below:
StartDate EndDate RoomsAvailable
----------------------------------------------
1-Jul-2015 3-Jul-2015 30
5-Jul-2015 7-Jul-2015 28
8-Jul-2015 9-Jul-2015 30
10-Jul-2015 10-Jul-2015 26
11-Jul-2015 12-Jul-2015 28
Please help..
Upvotes: 0
Views: 148
Reputation: 12317
If there's a lot of data, recursive CTE might not be the best solution. There is also a little trick that you can use. If you use datediff and row_number to group the dates together, you'll get the result this way:
select
min(bookdate),
max(bookdate),
rooms
from (
select
bookdate,
rooms,
datediff(day, 0, bookdate) - row_number()
over (partition by rooms order by bookdate asc) as DATEGRP
from
Reservation
) X
group by
DATEGRP,
rooms
order by 1
Here the datediff from day 0 increases always by 1 when bookdate increases by one, and of also row number increases by one, they are consecutive days. Partition by makes sure that only days with same availability get consecutive numbers. Grouping the result with that and using min / max will bring the start and end dates.
Upvotes: 1
Reputation: 2281
Try below query
DECLARE @Reservation TABLE ( BookDate DATE, ROOMS INT)
INSERT INTO @Reservation VALUES
('1-Jul-2015',30 ),
('2-Jul-2015',30 ),
('3-Jul-2015',30 ),
('5-Jul-2015',28 ),
('6-Jul-2015',28 ),
('7-Jul-2015',28 ),
('8-Jul-2015',30 ),
('9-Jul-2015',30 ),
('10-Jul-2015',26 ),
('11-Jul-2015',28 ),
('12-Jul-2015',28 )
;WITH
cte AS (
select ROW_NUMBER() OVER(ORDER BY BookDate) AS RowNumber,
[ROOMS], BookDate FROM @Reservation
),
cte2 as (
SELECT TOP 1 RowNumber, 1 as GroupNumber, [ROOMS], BookDate FROM cte ORDER BY RowNumber
UNION ALL
SELECT c1.RowNumber,
CASE WHEN c2.[ROOMS] <> c1.[ROOMS] then c2.GroupNumber + 1 ELSE c2.GroupNumber END AS GroupNumber, c1.[ROOMS], c1.BookDate
FROM cte2 c2 join cte c1 on c1.RowNumber = c2.RowNumber + 1
)
SELECT Start_Date, End_Date, Rooms
FROM
( SELECT MIN(BookDate) AS START_DATE, MAX(BookDate) AS END_DATE ,ROOMS, GroupNumber
FROM cte2
GROUP BY ROOMS ,GroupNumber
) a
Upvotes: 3
Reputation: 45
At first glance I would suggest GROUP BY 'RoomsAvailable' whilst the SELECT would be something like MIN(Date) StartDate, MAX(Date) EndDate
Upvotes: -2