用Sql计算酒店的高峰容量

用Sql计算酒店的高峰容量,sql,oracle,oracle11gr2,Sql,Oracle,Oracle11gr2,有许多旅馆有不同的床位容量。我需要知道,在任何一天,每家酒店都有多少张床位 样本数据: HOTEL CHECK-IN CHECK-OUT A 29.05.2010 30.05.2010 A 28.05.2010 30.05.2010 A 27.05.2010 29.05.2010 B 18.08.2010 19.08.2010 B 16.08.2010 20.08.2

有许多旅馆有不同的床位容量。我需要知道,在任何一天,每家酒店都有多少张床位

样本数据:

 HOTEL      CHECK-IN     CHECK-OUT
   A       29.05.2010   30.05.2010
   A       28.05.2010   30.05.2010
   A       27.05.2010   29.05.2010
   B       18.08.2010   19.08.2010
   B       16.08.2010   20.08.2010
   B       15.08.2010   17.08.2010
中间结果:

HOTEL      DAY          OCCUPIED_BEDS
  A     27.05.2010           1      
  A     28.05.2010           2
  A     29.05.2010           3
  A     30.05.2010           2
  B     15.08.2010           1
  B     16.08.2010           2
  B     17.08.2010           2
  B     18.08.2010           2
  B     19.08.2010           2
  B     20.08.2010           1
最终结果:

 HOTEL     MAX_OCCUPATION  
   A            3
   B            2

我想得到两个日期之间的日期列表,并通过分组计算每天的容量。问题是我的表相对较大,我想知道是否有成本较低的方法来完成此任务。

创建一个临时表,其中包含您感兴趣的天数

create table #dates (dat datetime)
insert into #dates (dat) values ('20121116')
insert into #dates (dat) values ('20121115')
insert into #dates (dat) values ('20121114')
insert into #dates (dat) values ('20121113')
通过将预订与日期合并,以生成每个预订日一个,从而获得中间结果

SELECT Hotel, d.dat, COUNT(*) from bookings b
INNER JOIN #dates d on d.dat BETWEEN b.checkin AND b.checkout
GROUP BY Hotel, d.dat 
A终于得到了最大值

SELECT Hotel, Max(OCCUPIED_BEDS) FROM IntermediateResult GROUP BY Hotel

我认为没有比你在问题中概述的方法更好的方法了。创建天数表或动态生成一个。我个人喜欢一年更新一次

理解分析函数的人可能不需要内部/外部查询就可以做到这一点,但由于内部分组是外部分组的子集,所以没有太大区别

Select
  i.Hotel,
  Max(i.OccupiedBeds)
From (
  Select
    s.Hotel,
    d.DayID,
    Count(*) As OccupiedBeds
  From
    SampleData s
      Inner Join
    Days d
      -- might not need to +1 depending on business rules.
      -- I wouldn't count occupancy on the day I check out, if so get rid of it
      On d.DayID >= s.CheckIn And d.DayID < s.CheckOut + 1 
  Group By
    s.Hotel, 
    d.DayID
  ) i
Group By
  i.Hotel
玩了一段时间后,如果没有内部查询,我无法让分析函数版本正常工作:

如果速度确实是一个问题,你可以考虑在主表上保持一个带有触发器的中间表。< /P>


性能方面的问题是连接条件不是基于相等的,这使得哈希连接不可能。假设我们有一个有两人一组的桌上旅馆日,我会尝试这样的方式:

select ch_in.hotel, ch_in.day,
       (check_in_cnt - check_out_cnt) as occupancy_change
from   ( select d.hotel, d.day, count(s.hotel) as check_in_cnt
         from   hotel_days d,
                sample_data s
         where  s.hotel(+) = d.hotel
           and  s.check_in(+) = d.day
         group  by d.hotel, d.day
       ) ch_in,
       ( select d.hotel, d.day, count(s.hotel) as check_out_cnt
         from   hotel_days d,
                sample_data s
         where  s.hotel(+) = d.hotel
           and  s.check_out(+) = d.day
         group  by d.hotel, d.day
       ) ch_out
where  ch_out.hotel = ch_in.hotel
  and  ch_out.day = ch_in.day

折衷的办法是双全扫描,但我认为它仍然会运行得更快,而且可能会并行化。我假设样本数据很大,主要是因为预订数量,而不是酒店本身的数量。输出是特定酒店在特定日期的入住率变化,但这可以通过分析功能或更有效的批量收集PL/SQL过程轻松地总结为总值。

可能是重复的,实际上不是重复的。海报没有中间结果。他有样本数据哦,是的,这就是挑战。我明白了。这是一个OLAP环境。您是否知道创建跨越6年的天数表的实用方法,即01.01.2008-01.12.2013