我正在开发 Rails 5 应用。
我有一个 Ride 模型和一个 Driver 模型。 每次乘车都有一个 scheduled_at 和一个 driver_id (belongs_to) 字段。 创建新 Ride 时,driver_id 为 NULL。然后司机可以接受还没有司机的游乐设施,所以为了向司机显示他可以接受的所有游乐设施,我在我的司机模型中创建了:
def open_rides
Ride.where('driver_id IS NULL')
end
棘手的部分是,我想从 open_rides 中排除所有行程,其中司机已经有相同 scheduled_at 日期时间或接下来 3 小时的行程。
换句话说,我想确保已经接受了时间 X 的行程的司机在时间 X 和接下来的 3 小时内看不到任何行程。
我希望能够在我的 open_rides 方法中将其表述为 WHERE,但我们非常欢迎任何其他想法。
这是一个例子:
我的驱动程序表中有一个驱动程序:
{
id: 1,
name: 'Thommy'
}
我的游乐设施表中有 3 个游乐设施:
{
id: 1,
scheduled_at: 2018-04-04 12:00:00,
driver_id: 1
},
{
id: 2,
scheduled_at: 2018-04-04 13:00:00,
driver_id: NULL
},
{
id: 3,
scheduled_at: 2018-04-04 20:00:00,
driver_id: NULL
}
司机已经分配给 Ride #1。 Ride #2 还没有司机,但 Ride #2 的 scheduled_at 与司机已经接受的另一个 Ride(在本例中为 Ride #1)相距 3 小时范围内,因此不应包含在 open_rides 中)。 行程 #3 没有司机,距离司机已经接受的行程超过 3 小时,应该包含在 open_rides 中。
最佳答案
您的 open_rides 方法应该查询 3 小时范围外的 NULL driver_id 的行程,因此您必须传递所有计划的驱动器日期(dateParam 列表)以从该方法中过滤掉。
select * from ride
where driver_id is null
and (scheduled_at < @dateParam and scheduled_at > @dateParam + INTERVAL 3 HOUR)
您必须为司机预订行程的日期列表中的每个 dateParam 添加一个 and 语句,例如:
select * from ride
where driver_id is null
and (scheduled_at < @dateParam and scheduled_at > @dateParam + INTERVAL 3 HOUR)
and (scheduled_at < @dateParam1 and scheduled_at > @dateParam1 + INTERVAL 3 HOUR)
and (scheduled_at < @dateParam2 and scheduled_at > @dateParam1 + INTERVAL 3 HOUR)
我不太熟悉 MySQL 或 Rails,但我想你可以这样做,虽然这可能不是最好的方法,但它将处理留给了数据库。 另一种选择是使用 driver_id null 加载所有游乐设施,并在 open_rides 方法中进行过滤,这可能更容易但内存效率不高,因为会有大量开放的游乐设施。
关于mysql - 棘手的 SQL 查询,条件来自两个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49194660/