在使用SQL Server 2012或更高版本的系统中,您可以
LAG()用来获取上一个最终日期并调整初始日期:
with ReservationAdjusted as (select *, lag(LastDay) over(partition by HouseID order by InitialDay, LastDay) as PreviousLastfrom Reservation)select HouseId, sum(case when PreviousLast>LastDay then 0 -- fully contained in the previous reservation when PreviousLast>=InitialDay then datediff(day,PreviousLast,LastDay) -- overlap else datediff(day,InitialDay,LastDay)+1 -- no overlap end) as Daysfrom ReservationAdjustedgroup by HouseId
情况是:
- 该保留项完全包含在先前的保留项中:我们只需要比较结束日期,因为前一行是按获取的
InitialDay, LastDay
,因此先前的开始日期始终小于或等于当前的开始日期。 - 当前的预订与之前的预订重叠:在这种情况下,我们调整起点,不加1(已经计算了起始日期),这种情况包括前一个终点等于当前的起点(是一天的重叠) 。
- 没有重叠:我们只计算差值,然后加1即可计算出第一天的时间。
请注意,我们不需要额外的条件来保留a,
HouseID因为默认情况下该
LAG()函数
NULL在没有上一行时返回,并且与null的比较始终为false。
样本输入和输出:
| HouseId | InitialDay | LastDay ||---------|------------|------------|| 1 | 2017-09-18 | 2017-09-20 || 1 | 2017-09-18 | 2017-09-22 || 1 | 2017-09-21 | 2017-09-22 || 19 | 2017-09-18 | 2017-09-27 || 19 | 2017-09-24 | 2017-09-26 || 19 | 2017-09-29 | 2017-09-30 || 20 | 2017-09-19 | 2017-09-22 || 20 | 2017-09-22 | 2017-09-26 || 20 | 2017-09-24 | 2017-09-27 || HouseId | Days ||---------|------|| 1 | 5 || 19 | 12 || 20 | 9 |



