在时间范围内确认资源是否足够

时间:2017-03-30 07:01:17

标签: sql ruby-on-rails algorithm postgresql search

我需要一个如何解决以下问题的想法。

假设我有一个给定时间范围的组(8:00-12:00),我可以为其分配资源(人员)。每个资源都可以有一个自定义时间范围(如9-10,9-12,8-12等),并且可以多次分配。

ID, 标题, 开始时间, 时间结束, REQUIRED_PEOPLE:INTEGER

PeopleAssignments

ID, 用户身份, GROUP_ID, 开始时间, END_TIME

现在我有这样的规则:在组时间范围内的任何给定时间,必须分配4人。否则我想收到警告。

我正在使用ruby& sql(Postgres)在这里。

是否有一种优雅的方式,没有遍历整个时间框架并检查计数(分配)> REQUIRED_PEOPLE

2 个答案:

答案 0 :(得分:0)

在任何情况下,您都需要查询DB中的分配数量。没有其他方法可以找到一个小组分配给人的次数。

可能有方法可以找到分配数量,但最后您必须向DB发出查询。

@group = Group.find(id)
if @group.people_assignments.count >= REQUIRED_PEOPLE
  pus 'warning'
end

您可以在组中添加额外列,其中包含该组分配给人员的次数。通过这种方式,对服务器的一个查询减少了。

@group = Group.find(id)
if @group.count_people_assigned >= REQUIRED_PEOPLE
  puts 'warning'
end

在第二种情况下,count_people_assigned是列,因此在第一种情况下people_assignments是关联时不会执行额外的查询,因此会触发一个额外的查询。

但在第二种情况下,每次将人员分配给人员时,您都可以更新组。最终额外的查询。您可以选择减少查询的位置。

我的观点是第二种情况,它会比第一种情况少见。

答案 1 :(得分:0)

您也可以仅使用SQL解决此问题(如果您对此类答案感兴趣)。

functions and operators提供了很棒的http://rextester.com/GRC64969来计算。

当存在子范围时,这些解决方案将为您提供行,其中存在来自给定组的一些缺失人员(并且它将为您提供正确的子范围以及所需的人数缺失的人数)数)。

简单方法:

你想尝试类似的东西。您需要选择df1 = df[player_columns].stack() print (df1) 0 Player 1 Thiem D. Player 2 Almagro N. 1 Player 1 Almagro N. Player 2 Ferrer D. 2 Player 1 Nadal R. Player 2 Thiem D. dtype: object print (df1[df1.map(d).isnull()].unique()) ['Almagro N.'] 基于的某个时间间隔(我选择了count()):

5 minutes

但请注意,当它们小于select g.id group_id, i start_time, i + interval '5 minutes' end_time, g.required_people - count(a.id) from groups g cross join generate_series(g.start_time, g.end_time, interval '5 minutes') i left join people_assignments a on a.group_id = g.id where tsrange(a.start_time, a.end_time) && tsrange(i, i + interval '5 minutes') group by g.id, i having g.required_people - count(a.id) > 0 order by g.id, i 时,您将无法检测到缺失的子范围。 F.ex. user1具有5 minutes的分配,而user2有11:00-11:56的分配,它们将显示在11:59-13:00的“组”中(因此11:00-13:00的缺失子范围将不被注意的。)

注意:间隔越短(你选择了什么),结果就越精确(和慢!)。

custom aggregates

艰难的方式

您可以使用recursive CTEshttp://rextester.com/GHPD52861

动态累积结果
11:56-11:59

http://localhost:5000/api/iterators/opel/next