从查询中获取最繁忙的员工

时间:2016-06-08 14:13:00

标签: ruby-on-rails ruby

我有两种模式:

# Table name: work_schedules
#
#  id          :integer          not null, primary key
#  start_time  :time             not null
#  end_time    :time             not null
#  day_of_week :string           not null
#  updated_at  :datetime         not null
#  person_id   :integer

# Table name: people
#
#  id                         :integer          not null, primary key
#  pesel                      :string           not null
#  first_name                 :string           not null
#  last_name                  :string           not null

我希望在查询中找到最忙碌的员工。 首先,我应该计算小时数(end_time - start_time)并计算day_of_week(唯一属性范围:person_id)。我不知道如何正确创建查询。 我尝试了什么:

@most_busy = Person.joins(:work_schedules).where(%q{end_time - start_time}).first

1 个答案:

答案 0 :(得分:1)

对于一周中的所有日子(即,在一周的所有日子里总结): WorkSchedule.group(:person_id).sum('extract(epoch from work_schedules.end_time) -extract(epoch from work_schedules.start_time)').sort_by { |_,v| -v}.first.first

这将为您提供在所有WorkSchedules上工作最多的人员的ID。我只用PostgreSQL测试过它。

此查询中发生了什么:

  1. 获取所有工作计划对象并按人员ID分组
  2. 对于这些工作计划组中的每一个,获取开始和结束时间之间的差异总和。提取时代告诉SQL将时间戳记作为整数(UNIX时间戳,我相信)。这是必要的,因为否则查询的结果会将这些总和作为字符串给出,例如“17天136:57:42.748124”,ruby无法正确排序。
  3. SQL查询会生成{person_id:time_scheduled_in_seconds}形式的哈希值。
  4. sort_by以与值相反的方式对查询进行排序。我们没有使用散列中的键,因此我们使用下划线而不是名称来忽略它们。
  5. 然后我们取这个哈希中的第一个项目(因此第一个“.first”)。
  6. 因为它实际上返回一个数组,其中person_id为第一个值,秒数为第二个值,我们只保留第一个项目(因此第二个“.first”)