首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取重叠日期的房价

获取重叠日期的房价
EN

Stack Overflow用户
提问于 2017-08-29 12:01:29
回答 5查看 172关注 0票数 2

我在这个结构里有桌子:

代码语言:javascript
复制
id  accom_id    room_type_id    date_from   date_to        price_per_room   
3   1           2               2017-09-01  2017-09-10     70.00    
5   1           2               2017-09-11  2017-09-20     100.00

假设我想住在2017-09-07 - 2017-09-15。因此,使用DATEDIFF,我需要计算多少天的价格是70和多少天的价格是100。最后,我想展示一下总数。

有人能帮我构建这个查询吗?我希望这是清楚的要求!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-08-29 12:17:27

假设没有定义重叠范围,并且假定所有给定的范围都是包容性的,那么我们可以使用CTE获得数据,然后进行简单的聚合:

代码语言:javascript
复制
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表达式正在做的事情。如果我们有按日期操作的标量MINMAX函数,我更愿意使用这些函数,但是没有内置到Server中的函数。

票数 2
EN

Stack Overflow用户

发布于 2017-08-29 12:24:06

在Server中,您可以这样做:

代码语言:javascript
复制
select dateadd(d, number, '20170801')
from master.dbo.spt_values
where type='P' and (number <= datediff(d, '20170801', '20170810'))

计算总天数(在where子句中),选择从0到总天数的数字(master.dbo.spt_values在Server中是一个有用的表)。否则,您可以创建一个从0到?的提升数字的表。然后你把这个数字加到起始日期。所以你有一整天的预订时间:

代码语言:javascript
复制
2017-08-01 
2017-08-02 
2017-08-03 
2017-08-04 
2017-08-05 
2017-08-06 
2017-08-07 
2017-08-08 
2017-08-09 
2017-08-10 

然后,您可以在date_from和date_to上加入给定的date_to,然后计算您的和。

编辑:就为了完成它..。:-)

代码语言:javascript
复制
SELECT SUM(price_per_room)
FROM master.dbo.spt_values
    LEFT OUTER JOIN room_prices AS rp ON (date_from <= DATEADD(d, number, my_start_date) AND DATEADD(d, number, my_start_date) <= date_to)
WHERE type='P' AND (number <= DATEDIFF(d, my_start_date, my_end_date))
票数 0
EN

Stack Overflow用户

发布于 2017-08-29 12:15:12

您可以使用日历或日期表来处理这类事情。

在不执行创建表的实际步骤的情况下,您可以使用具有如下所示的公共表表达式的临时日期表:

代码语言:javascript
复制
declare @fromdate date = '20170907';
declare @thrudate date = '20170915';
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
  select top (datediff(day, @fromdate, @thrudate)+1) 
      [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
  from n as deka cross join n as hecto cross join n as kilo
                cross join n as tenK cross join n as hundredK
   order by [Date]
)
select total_price = sum(price_per_room)
from dates d
  inner join t
    on d.date >= t.date_from
   and d.date <= t.date_to

rextester演示:http://rextester.com/MCF52261

返回:

代码语言:javascript
复制
+-------------+
| total_price |
+-------------+
|         780 |
+-------------+

要了解更详细的价格和日期,您可以将上面的select换成这个:

代码语言:javascript
复制
select 
    fromdate = min(date)
  , thrudate = max(date)
  , days = count(*)
  , price_per_room = avg(price_per_room)
  , total = sum(price_per_room)
from dates d
  inner join t
    on d.date >= t.date_from
   and d.date <= t.date_to
group by grouping sets ((price_per_room),())

rextester演示:http://rextester.com/NKZD1468

返回:

代码语言:javascript
复制
+------------+------------+------+----------------+-------+
|  fromdate  |  thrudate  | days | price_per_room | total |
+------------+------------+------+----------------+-------+
| 2017-09-07 | 2017-09-10 |    4 | 70             |   280 |
| 2017-09-11 | 2017-09-15 |    5 | 100            |   500 |
| 2017-09-07 | 2017-09-15 |    9 | 86             |   780 |
+------------+------------+------+----------------+-------+

编号和日历表参考:

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45938635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档