假设没有重叠范围定义,并且假设所有给定的意在为包括性的范围的,我们可以使用获得的数据CTE然后一个简单的聚合问题:
declare @t table (date_from date,date_to date, price_per_room int)
insert into @t (date_from,date_to,price_per_room) values
('20170901','20170910',70.00),
('20170911','20170920',100.00)
declare @Start date
declare @End date
select @Start = '20170907',@End = '20170915'
;With IncludedPeriods as (
select
CASE WHEN @Start > date_from THEN @Start ELSE date_from END as fromDT,
CASE WHEN @End < date_to THEN @End ELSE date_to END as ToDT,
price_per_room
from
@t
where
date_from <= @End and
@Start <= date_to
)
select
SUM(price_per_room * (1 + DATEDIFF(day,fromDT,ToDT)))
from
IncludedPeriods
注意,我们要添加一个到DATEDIFF
结果,因为它计算过渡,但我假设一段从“20170911” 到“20170911”应该算作一天,同样更长的时间。
不像其中一些试图枚举各种“箱子”为重叠其他的答案的,这里采用的简单的规则 - 两个周期重叠,如果第二前的第一次启动结束和如果第一端部之前的第二开始 - 这是CTE内where
条款中应用的逻辑。为了确定重叠的范围,我们选取两个开始日期中较晚的一个和两个结束日期中较早的一个 - 这就是CASE
表达式正在做的事情。如果我们在日期上使用了标量MIN
和MAX
函数,我宁愿使用这些函数,但没有内置到SQL Server中的函数。
请不要使用不适用于您的问题的标签。我删除了数据库标记,因为它不清楚你实际使用了哪一个。请添加仅*的标签*您实际使用的数据库 –
在[所以]您应该尝试**自己编写代码**。后** [做更多的研究](//meta.stackoverflow.com/questions/261592)**如果你有问题,你可以**发布你已经尝试**与清楚的解释是什么是'工作**并提供[** Minimal,Complete和Verifiable示例**](// stackoverflow.com/help/mcve)。我建议阅读[问]一个好问题和[完美问题](http://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/)。另外,一定要参加[游览]并阅读[this](// meta.stackoverflow.com/questions/347937/)**。 –
我们保证要查询的所有日期将覆盖行并且不存在重叠行(即从未需要提供默认值或用于消除行歧义的规则)? –