查询方法#group如何工作?

时间:2014-05-31 00:20:39

标签: ruby-on-rails querying

我正在学习rails并且一直在尝试阅读文档,但我还是不知道如何#group  的工作原理。

文档说它:"根据组属性"返回一个具有不同记录的数组。

然后如何检索属于某个群组的记录?

说我想按照创建它们的月份对Articles进行分组?我该怎么办?

1 个答案:

答案 0 :(得分:3)

group方法通常与select方法一起使用来进行聚合查询。例如,如果您希望按月计算您的文章,则可以执行以下操作:

by_month = Article.group(:month).select("month", "COUNT(*) as count")

在这种情况下,COUNT是计算行数的SQL聚合函数,我们将计数结果放入名为" count"的输出列中。

注意:这假设您有一个名为" month"的列。当然你可以在这里做SQL,所以你可能会这样做,例如MONTH(created_at)代替,或者在你的情况下有意义。

然后,您可以执行此操作以输出月份及其相关的文章计数:

by_month.each do |row|
   puts "Month #{row.month}: #{row.count}"
end

这可能看起来很神秘,因为你的模型没有列"计数",但这就是select的工作方式:它为动态查询定义新的输出列,以及ActiveRecord在生成的实例对象中愉快地映射了那些。

这种查询比加载所有记录并自己计算更有效率,因为您让数据库执行繁重的数据工作,以及它擅长的是什么。

在没有group的情况下使用select是完全合法的,但结果通常不是您想要的。如果按月对文章进行分组,则每个月都会在结果中获得一个对象。每个对象中可用的列因数据库后端而异,但在MySQL中,它们将具有来自" first"每个组遇到的行。如果你没有排序,首先"基本上是未定义的。

如果按照"分组文章创建它们的月份"你的意思是你想在网页结果上进行这种分组,那么你必须自己做,例如:

<% last_month = nil %>
<% @articles.each do |article| %>
   <% if last_month != article.month %>
      <h2><%= article.month %></h2>
      <% last_month = article.month %>
   <% end %>

   # [output the article]

<% end %>

如果您执行此类操作,则需要确保按月排序@articles