如何编写一个Rails finder方法,它将返回按记录分组的最大日期?

Dav*_*ave 5 postgresql ruby-on-rails ruby-on-rails-5

我正在使用PostGres 9.5的Rails 5.我有一张跟踪价格的桌子......

                                         Table "public.crypto_prices"
       Column       |            Type             |                         Modifiers
--------------------+-----------------------------+------------------------------------------------------------
 id                 | integer                     | not null default nextval('crypto_prices_id_seq'::regclass)
 crypto_currency_id | integer                     |
 market_cap_usd     | bigint                      |
 total_supply       | bigint                      |
 last_updated       | timestamp without time zone |
 created_at         | timestamp without time zone | not null
 updated_at         | timestamp without time zone | not null
Run Code Online (Sandbox Code Playgroud)

我想得到last_updated所选货币的最新每种货币价格(哪里最大).我可以找到与某些货币相关的所有价格

current_prices = CryptoPrice.where(crypto_currency_id: CryptoIndexCurrency.all.pluck(:crypto_currency_id).uniq)
Run Code Online (Sandbox Code Playgroud)

然后我可以按货币对数组进行排序,循环遍历每个数组,直到找到last_updated价值最大的那个,但是我如何编写一个查找器,每个货币最多可以返回最多一行last_updated

编辑:尝试过Owl Max的建议

ids = CryptoIndexCurrency.all.pluck(:crypto_currency_id).uniq
crypto_price_ids = CryptoPrice.where(crypto_currency_id: ids).group(:crypto_currency_id).maximum(:last_updated).keys
puts "price ids: #{crypto_price_ids.length}"
@crypto_prices = CryptoPrice.where(crypto_currency_id: crypto_price_ids)
puts "ids: #{@crypto_prices.size}"
Run Code Online (Sandbox Code Playgroud)

虽然第一个"看跌期权"仅显示"12"的大小,但第二个看跌期权显示超过38,000个结果.它应该只返回12个结果,每个货币一个.

Kru*_*pös 0

or由于查询方法的原因,仅适用于 Rails5

specific_ids = CryptoIndexCurrency.distinct.pluck(:crypto_currency_id)
hash = CryptoPrice.where(crypto_currency_id: specific_ids)
                  .group(:crypto_currency_id)
                  .maximum(:last_updated)
hash.each_with_index do |(k, v), i|
  if i.zero?
    res = CryptoPrice.where(crypto_currency_id: k, last_updated: v)
  else
    res.or(CryptoPrice.where(crypto_currency_id: k, last_updated: v))
  end
end
Run Code Online (Sandbox Code Playgroud)

解释

您可以通过表格中的每个礼物group来重新组合所有对象。CryptoPriceCryptoIndexCurrency

然后使用maximum(感谢@artgb)取最大值last_updated。这将输出Hash带有keys:crypto_currency_id和value 的a last_updated

最后,您可以使用keys仅获取Arrayof crypto_currency_id

CryptoPrice.group(:crypto_currency_id).maximum(:last_updated)
=> => {2285=>2017-06-06 09:06:35 UTC,
       2284=>2017-05-18 15:51:05 UTC,
       2267=>2016-03-22 08:02:53 UTC}
Run Code Online (Sandbox Code Playgroud)

此解决方案的问题在于您获取每行的最大日期而没有获取整个记录。

要获取记录,您可以成对地对哈希进行循环。与crypto_currency_idlast_updated。这很hacky,但却是我找到的唯一解决方案。