Postgres,Rails 4,Heroku - 按列分组,但选择所有列

时间:2014-08-01 16:43:11

标签: postgresql ruby-on-rails-4 heroku group-by

这个问题可能是重复的,但在阅读了类似问题的各种答案后,我还没有创建一个有效的解决方案。

我在rails 4中有模型Post。我们可以想象它只有idcreated_atupdated_atbody属性。

我的目标是在创建日期之前归还posts。我的第一次尝试是:

Post.group('date(created_at')转换为SELECT "posts".* FROM "posts" GROUP BY date(created_at)

这会产生错误

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "posts.id" must appear in the GROUP BY clause or be used in an aggregate function

我的理解是这个错误是因为Postgres需要您在组方法中包含SELECT的列。我的困惑在于,据我所知,在group子句中包含所有列将导致它们不被分组。我的预感是我错过的是错误的最后部分:

or be used in an aggregate function

这就是我所处的位置,我不确定“聚合函数”是什么意思,最终,我仍然不知道如何group我的posts创建之日。

如果您需要更多详细信息,请询问,我会添加它们。

1 个答案:

答案 0 :(得分:0)

我不认为SQL GROUP BY是这项工作的正确工具,Enumerable#group_by是您正在寻找的石斑鱼。

SQL's GROUP BY是:

  

[...]用于将表中列中所有列中具有相同值的行组合在一起。列列的顺序无关紧要。效果是将具有共同值的每组行组合到一个组行中,该组行表示组中的所有行。这样做是为了消除输出中的冗余和/或计算适用于这些组的聚合。

因此您使用GROUP BY来收集具有共同点的行,以便您可以忽略它们的差异或将聚合应用于每个组(例如,查找每组极值,计算每个组的大小,每组平均值,。 ..)。当你GROUP BY时,原始行或多或少都是他们的独立身份。

如果您要对结果进行分页,请按date(created_at)排序以获得合理的网页,并在Ruby-land中使用Enumerable#group_by来制作要展示的内容:

posts   = Post.where(...).order('date(created_at)')...
by_date = posts.group_by { |p| p.created_at.to_date }

by_date中留下一个很好的简单哈希,它将日期映射到Post的数组。显示by_date内容应该非常简单。

如果您没有进行分页,那么您根本不需要在数据库中订购所有内容,只需将其全部拉出(posts = Post.where(...)...)并继续{{{ 1}}如上所述。

相关问题