这个问题可能是重复的,但在阅读了类似问题的各种答案后,我还没有创建一个有效的解决方案。
我在rails 4中有模型Post
。我们可以想象它只有id
,created_at
,updated_at
和body
属性。
我的目标是在创建日期之前归还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
创建之日。
如果您需要更多详细信息,请询问,我会添加它们。
答案 0 :(得分:0)
我不认为SQL GROUP BY是这项工作的正确工具,Enumerable#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}}如上所述。