SQL Server查询 - 计算房间的可用性

时间:2015-07-07 13:18:38

标签: sql sql-server tsql sql-server-2008-r2 sql-server-2012

我的表名RoomInventory包含如下数据

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 

我想要的结果如下:

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 

请帮助..

3 个答案:

答案 0 :(得分:3)

尝试以下查询

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

SQLFiddler Demo

答案 1 :(得分:1)

如果有大量数据,递归CTE可能不是最佳解决方案。还有一个小技巧,你可以使用。如果您使用datediff和row_number将日期分组在一起,您将以这种方式获得结果:

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

此处,当第0天增加1时,第0天的日期增加总是增加1,并且行数增加1,它们是连续的天数。分区确保只有具有相同可用性的天数才能获得连续数字。使用该分组结果并使用min / max将带来开始和结束日期。

SQL Fiddle

答案 2 :(得分:-2)

乍一看,我建议GROUP BY&#39; RoomsAvailable&#39;而SELECT将是MIN(Date)StartDate,MAX(Date)EndDate

相关问题