我的DBA经验远不止于简单存储+检索CMS样式数据,还有很多,所以这可能是一个愚蠢的问题,我不知道!
我遇到一个问题,我需要查询或计算特定时间段内特定群体人数和特定天数的假期价格。例如:
一月份任何时候可供4人入住2晚的酒店客房多少钱?
我有像这样存储的5000家酒店的价格和空房数据:
Hotel ID | Date | Spaces | Price PP
-----------------------------------
123 | Jan1 | 5 | 100
123 | Jan2 | 7 | 100
123 | Jan3 | 5 | 100
123 | Jan4 | 3 | 100
123 | Jan5 | 5 | 100
123 | Jan6 | 7 | 110
456 | Jan1 | 5 | 120
456 | Jan2 | 1 | 120
456 | Jan3 | 4 | 130
456 | Jan4 | 3 | 110
456 | Jan5 | 5 | 100
456 | Jan6 | 7 | 90
使用此表,我可以像这样进行查询:
SELECT hotel_id, sum(price_pp)
FROM hotel_data
WHERE
date >= Jan1 and date <= Jan4
and spaces >= 2
GROUP BY hotel_id
HAVING count(*) = 4;
结果
hotel_id | sum
----------------
123 | 400
HAVING
此处的条款确保在我希望的日期之间的每一天都有一个可用空格的条目。即。456号酒店在1月2日有1个可用空间,HAVING子句将返回3,因此我们没有得到456号酒店的结果。
到目前为止,一切都很好。
但是,有没有办法找出一月份有可用空间的所有四个夜晚?我们可以重复查询27次-每次增加日期,这似乎有点尴尬。或者另一种解决方法是将所有可能的组合存储在查找表中,如下所示:
Hotel ID | total price pp | num_people | num_nights | start_date
----------------------------------------------------------------
123 | 400 | 2 | 4 | Jan1
123 | 400 | 2 | 4 | Jan2
123 | 400 | 2 | 4 | Jan3
123 | 400 | 3 | 4 | Jan1
123 | 400 | 3 | 4 | Jan2
123 | 400 | 3 | 4 | Jan3
等等。我们必须限制最大夜晚数,并且要搜索的最大人数-例如,最大夜晚= 28,最大人数= 10(限制为从该日期开始的那个设定时间段内的可用空间数)。
对于一家酒店,这每年可以为我们带来28 * 10 * 365 = 102000个结果。5000家酒店= 500m个结果!
但我们将有一个非常简单的查询,以查找2人在1月最便宜的4晚住宿:
SELECT
hotel_id, start_date, price
from hotel_lookup
where num_people=2
and num_nights=4
and start_date >= Jan1
and start_date <= Jan27
order by price
limit 1;
有没有一种方法可以在初始表上执行此查询,而不必生成500m行查找表!例如在临时表或其他内部查询魔术中生成27种可能的结果?
目前,所有数据都保存在Postgres数据库中-如果出于此目的,我们可以将数据移至其他更合适的位置?不确定这种查询是否适合NoSQL样式数据库的映射/减少模式...