【发布时间】:2015-10-08 21:06:42
【问题描述】:
我有一个ParkingLot 模型。停车场有许多可用的lots。然后,用户可以预订一个或多天的停车场。因此我有一个Booking 模型。
class ParkingLot
has_many :bookings
end
class Booking
belongs_to :parking_lot
end
简化用例
停车场
给定一个有 5 个可用车位的停车场:
预订
- Bob 从周一到周日预订了一个地方
- Sue 在周一、周三和周五各进行一次预订
- Henry 只在星期五读书。
- 由于周末很忙,另外 4 人预订了周六至周日。
编辑
预订有一个start_date 和一个end_date,所以Bob 的预订只有一个 条目。 Mon-Sun。
另一方面,Sue 确实有三个预订,都在同一天开始和结束。 Mon-Mon, Wed-Wed, Fri-Fri.
这为我们提供了以下预订数据:
为简单起见,我将使用首字母 (B) 和工作日 (Mon),而不是用户 ID (1) 和日期 (2015-5-15)。
––––––––––––––––––––––––––––––––––––––––––
| id | user_id | start_date| end_date| ... |
|––––––––––––––––––––––––––––––––––––––––––|
| 1 | B | Mon | Sun | ... |
|––––––––––––––––––––––––––––––––––––––––––|
| 2 | S | Mon | Mon | ... |
| 3 | S | Wed | Wed | ... |
| 4 | S | Fri | Fri | ... |
|––––––––––––––––––––––––––––––––––––––––––|
| 5 | H | Fri | Fri | ... |
|––––––––––––––––––––––––––––––––––––––––––|
| 6 | W | Sat | Sun | ... |
| 7 | X | Sat | Sun | ... |
| 8 | Y | Sat | Sun | ... |
| 9 | Z | Sat | Sun | ... |
––––––––––––––––––––––––––––––––––––––––––
这给了我们接下来的一周:
–––––––––––––––––––––––––––––––––––––––––
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
|–––––––––––––––––––––––––––––––––––––––––|
| B | B | B | B | B | B | B |
|–––––––––––––––––––––––––––––––––––––––––|
| S | - | S | - | S | - | - |
|–––––––––––––––––––––––––––––––––––––––––|
| - | - | - | - | H | - | - |
|–––––––––––––––––––––––––––––––––––––––––|
| - | - | - | - | - | W | W |
| - | - | - | - | - | X | X |
| - | - | - | - | - | Y | Y |
| - | - | - | - | - | Z | Z |
|=========================================|
| 2 | 1 | 2 | 1 | 3 | 5 | 5 | # Bookings Count
|=========================================|
| 3 | 4 | 3 | 4 | 2 | 0 | 0 | # Available lots
–––––––––––––––––––––––––––––––––––––––––
这些预订已经在数据库中,因此当新用户想要在周一至周五进行预订时,还有空间可以这样做。但是当他想从周一到周六预订时,这是不可能的。
我的目标是查询给定时间范围内的最大预订数。最终导致可用地段
# Mon - Thursday => max bookings: 2 => 3 available lots
# Mon - Friday => max bookings: 3 => 2 available lots
# Mon - Sunday => max bookings: 5 => 0 available lots
我的一个简单但错误的方法是获取给定时间范围内的所有预订:
scope :in_range, ->(range) { where("end_date >= ?", range.first).where("start_date <= ?", range.last) }
但这绝不是正确的。从星期一到星期五的查询返回 5 个预订,一个来自 Bob,一个来自 Henry,三个来自 Sue。这会错误地假设停车场已满。
如何创建这样的查询来获取给定时间范围内的最大预订数?
这也可以是纯SQL,我很乐意稍后翻译成AR。
【问题讨论】:
标签: sql ruby-on-rails activerecord date-range