【问题标题】:How to fetch records from last 7 days with padding to 0 if no records found?如果没有找到记录,如何获取过去 7 天的记录并填充为 0?
【发布时间】:2016-03-27 16:36:25
【问题描述】:

我正在尝试从过去 7 天(可能会更改以支持月份和年份)中获取记录以填充图表,并且我需要将未找到记录的日期填充为 0。我首先尝试分组但发现无法填充数据,所以我想出了这个:

today = Date.today

array_data = (today - 6.days..today).map do |day|  
  total_time = @project.time_entries.where(created_at: (day.beginning_of_day..day.end_of_day)).map(&:duration_hours).sum

  { day.strftime("%a %d %b") => total_time }
end

@entries_data = array_data.reduce Hash.new, :merge

结果是一个散列,其中一天为键,计算属性的总和为值。

但是,这需要每天进行一次数据库查询:

TimeEntry Load (1.1ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" IN ('bd9f541c-e37a-45de-bc94-28bef2b5eade')
  TimeEntry Load (0.4ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-21 04:30:00.000000' AND '2016-03-22 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-22 04:30:00.000000' AND '2016-03-23 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-23 04:30:00.000000' AND '2016-03-24 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-24 04:30:00.000000' AND '2016-03-25 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.5ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-25 04:30:00.000000' AND '2016-03-26 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.6ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-26 04:30:00.000000' AND '2016-03-27 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.5ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-27 04:30:00.000000' AND '2016-03-28 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]

我怎样才能修改它以使其仅向数据库发送 1 个查询?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    不确定这是您的意思,但我认为您需要这样做:

    • 运行查询以获取过去 N 天的所有数据。
    • 按天对这些记录进行分组
    • 在过去 N 天的每一天将其合并到值为 { date => 0} 的哈希之上

    【讨论】:

      【解决方案2】:

      好的,正如tpbowden 在他的回答中提到的那样,我设法将它减少到 1 个这样的查询:

      date_format = "%d %b"
      entries_last_week = time_entries.group_by { |t| t.created_at.to_date.strftime(date_format) }.map { |k, v| { k => v.map(&:duration_hours).sum } }
      entries_hash = entries_last_week.reduce Hash.new, :merge
      today = Date.today
      days = (today - 6.days..today).map { |day| { day.strftime(date_format) => 0 } }
      hash_of_days = days.reduce Hash.new, :merge
      
      hash_of_days.merge(entries_hash)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 2013-07-08
        相关资源
        最近更新 更多