【发布时间】:2010-09-30 00:56:43
【问题描述】:
查询:limit,我会得到前N条记录。获取最后 N 条记录的最简单方法是什么?
【问题讨论】:
标签: ruby-on-rails ruby activerecord
查询:limit,我会得到前N条记录。获取最后 N 条记录的最简单方法是什么?
【问题讨论】:
标签: ruby-on-rails ruby activerecord
这是 Rails 3 方式
SomeModel.last(5) # last 5 records in ascending order
SomeModel.last(5).reverse # last 5 records in descending order
【讨论】:
SELECT "items".* FROM "items" ORDER BY id DESC LIMIT 50
SomeModel.last(5).class == Array。正确的方法是 SomeModel.limit(5).order('id desc') per Arthur Neves,结果为 SELECT \"somemodels\".* FROM \"somemodels\" ORDER BY id desc LIMIT 5
你可以通过last方法简单地获取最后N条记录:
Record.last(N)
例子:
User.last(5)
按 id 降序返回 5 个用户。
我认为像这样的活动记录查询会得到你想要的('Something' 是模型名称):
Something.find(:all, :order => "id desc", :limit => 5).reverse
编辑:如 cmets 中所述,另一种方式:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
【讨论】:
在 Rails 3.1 中执行此操作的新方法是 SomeModel.limit(5).order('id desc')
【讨论】:
last(5) 更好,因为它返回了进一步链接的范围。
SomeModel.limit(100).reverse_order (guides.rubyonrails.org/…) 是一样的。
SomeModel.limit(5).order('id desc').pluck(:col) 将执行SELECT SomeModel.col FROM SomeModel ORDER BY id desc LIMIT 5,这比抓取所有列并丢弃除一列之外的所有列更有效带有SomeModel.last(5).map(&:col) 的列是SELECT * 而不是SELECT col(调用last 后不能采摘;lazy-eval 链以last 结束)。
Something.last(5)
因为:
Something.last(5).class
=> Array
所以:
Something.last(50000).count
可能会毁掉你的记忆或永远消失。
Something.limit(5).order('id desc')
因为:
Something.limit(5).order('id desc').class
=> Image::ActiveRecord_Relation
Something.limit(5).order('id desc').to_sql
=> "SELECT \"somethings\".* FROM \"somethings\" ORDER BY id desc LIMIT 5"
后者是一个未评估的范围。您可以链接它,或通过.to_a 将其转换为数组。所以:
Something.limit(50000).order('id desc').count
... 需要一秒钟。
【讨论】:
对于 Rails 4 及以上版本:
如果你想要第一个最旧的条目
,你可以尝试这样的事情YourModel.order(id: :asc).limit(5).each do |d|
如果您想要最近的最新条目,您可以尝试类似的方法。..
YourModel.order(id: :desc).limit(5).each do |d|
【讨论】:
YourModel.all.order(id: :desc).limit(5)
" "的新语法
YourModel.all.order(),因为与YourModel.order()相同
解决方案在这里:
SomeModel.last(5).reverse
由于 rails 是惰性的,它最终会使用如下 SQL 访问数据库:“SELECT table.* FROM table ORDER BY table.id DESC LIMIT 5”。
【讨论】:
SomeModel的所有记录
SELECT table.* FROM table` ORDER BY table.id DESC LIMIT 5` 它不执行全选
如果您需要对结果进行排序,请使用:
Model.order('name desc').limit(n) # n= number
如果您不需要任何排序,只需要保存在表中的记录,则使用:
Model.last(n) # n= any number
【讨论】:
在我的 rails (rails 4.2) 项目中,我使用
Model.last(10) # get the last 10 record order by id
它有效。
【讨论】:
试试吧:
Model.order("field_for_sort desc").limit(5)
【讨论】:
我们可以在 rails 5.2 中使用 Model.last(5) 或 Model.limit(5).order(id: :desc)
【讨论】:
我发现这个查询更好/更快地使用我喜欢的“pluck”方法:
Challenge.limit(5).order('id desc')
这给出了一个 ActiveRecord 作为输出;所以你可以像这样使用 .pluck :
Challenge.limit(5).order('id desc').pluck(:id)
在使用最佳 SQL 代码的同时快速将 id 作为数组提供。
【讨论】:
Challenge.limit(5).order('id desc').ids 也可以:)
假设 N = 5,你的模型是 Message,你可以这样做:
Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)
看sql:
SELECT "messages".* FROM (
SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT 5
) messages ORDER BY "messages"."created_at" ASC
关键是子选择。首先,我们需要定义我们想要的最后一条消息是什么,然后我们必须按升序对它们进行排序。
【讨论】:
如果您的模型中有一个默认范围指定 Rails 3 中的升序,您将需要使用重新排序而不是上面 Arthur Neves 指定的顺序:
Something.limit(5).reorder('id desc')
或
Something.reorder('id desc').limit(5)
【讨论】:
一个简单的答案是:
Model.limit(5).order(id: :desc)
这个解决方案有一个问题,因为id 不能成为记录何时创建的唯一确定者。
更可靠的解决方案是:
Model.order(created_at: :desc).limit(5)
正如其他人指出的那样,也可以使用Model.last(5)。唯一的问题是它返回Array,而不是Model::ActiveRecord_Relation。
【讨论】:
在查询中添加 :order 参数
【讨论】: