使用postgres搜索一些数据

时间:2016-01-18 17:00:35

标签: ruby-on-rails ruby postgresql

我正在使用pg,需要从db获取一些数据才能在我的页面上创建一个图表。

以下是表架构:

t.decimal  "balance",     precision: 16, scale: 2
t.datetime "created_at",                           null: false
t.datetime "updated_at",                           null: false

这是数据的一个例子

[#<Account:0x007f8a58b8aee0
  id: 1,
  balance: 5000,
  created_at: Sun, 16 Nov 2015 02:27:43 UTC +00:00,
  updated_at: Sun, 16 Nov 2015 02:27:43 UTC +00:00,
  order_id: nil>,
 #<Account:0x007f8a58b8aaf8
  id: 2,
  balance: 4000,
  created_at: Sun, 16 Nov 2015 15:05:07 UTC +00:00,
  updated_at: Sun, 16 Nov 2015 15:05:07 UTC +00:00,
  order_id: nil>,
 #<Account:0x007f8a58b8a7d8
  id: 3,
  balance: 3000,
  created_at: Sun, 15 Nov 2015 15:07:04 UTC +00:00,
  updated_at: Sun, 15 Nov 2015 15:07:04 UTC +00:00,
  order_id: nil>,
 #<Account:0x007f8a58b8a508
  id: 4,
  balance: 2000,
  created_at: Sun, 15 Nov 2015 15:12:32 UTC +00:00,
  updated_at: Sun, 15 Nov 2015 15:12:32 UTC +00:00,
  order_id: nil>,
 #<Account:0x007f8a58b8a148
  id: 5,
  balance: 1800,
  created_at: Sun, 13 Nov 2015 15:14:14 UTC +00:00,
  updated_at: Sun, 13 Nov 2015 15:14:14 UTC +00:00,
  order_id: nil>]

比如说下面是我想得到的愿望结果:

[4000, 2000, 1800, 1800, 1800]

结果的条件是: 1)我想获得最近5天的结果,因此数组总是有5个数据。 2)我必须获得当天的最新余额。 3)如果当天没有任何交易,余额将等于前一天的余额。

更新:

我试图从数据中得到一系列哈希值,如下所示:

Account.where("created_at > ?", Date.today - 5).map{|x| {x.created_at => x.balance}}

并获得以下结果:

[{Sun, 16 Nov 2015 02:27:43 UTC +00:00=>
   5000},
 {Sun, 16 Nov 2015 15:05:07 UTC +00:00=>
   4000},
 {Sun, 15 Nov 2015 15:07:04 UTC +00:00=>
   3000},
 {Sun, 15 Nov 2015 15:12:32 UTC +00:00=>
   2000},
 {Sun, 13 Nov 2015 15:14:14 UTC +00:00=>
   1800}]

我认为我在正确的道路上,现在我必须合并具有相同日期的密钥,并获得该日期的最新时间的值。知道我怎么能这样做吗?谢谢。

1 个答案:

答案 0 :(得分:2)

  

结果的条件是:1)我想得到结果   最近5天,所以数组总是有5个数据。 2)我必须得到   当天的最新余额。 3)如果有任何一天没有   交易,余额将等于当天的余额   之前。

获取过去5天的结果:

five_days_ago = Date.today - 5 # you can make a date diff just subtracting the number of days
Account.where("created_at > ?", five_days_ago)

获取每天的最新余额:您应该按日期获得余额,并获得created_at为最大值的那个。但是在Ruby处理输出时这可能更容易做到:

require 'date'

five_days_ago = Date.today - 5

query = Account.where("created_at > ?", Date.today - 5).map{|x| {x.created_at => x.balance}}
query = query.reduce({}, :merge) # reduce to one hash

# Create an hash with the dates and the latest created_at
dates = query.group_by{|k, v| Date.parse(k.to_s)}
dates.map{|k, v| {Date.parse(v.max.to_s) => v.max }

# Create an output hash including all dates
result = {}
last_available_balance = 0
(five_days_ago...Date.today).each do |d|

  if dates.keys.includes? d
    # assign the value corresponding to the latest timestamp
    last_available_balance = query[dates[d]]
    result[d] = last_available_balance

  else
    # keep the value of the last available balance
    result[d] = last_available_balance

  end
end