简体   繁体   English

如何将查询结果与活动记录分组?

[英]How to group a query result with active record?

I have the following model: 我有以下模型:

ProfileViews (id, user_id, viewer_id)

I am trying to return all user_views, which are grouped by viewer_id ... Note viewer_id can nil, which is something I want to return. 我正在尝试返回所有的user_views,它们都按viewer_id分组。请注意,viewer_id可以为nil,这是我想返回的内容。 I can say viewed 20 times by nil etc... 我可以说被nil等浏览了20次...

Why does this not work? 为什么这不起作用?

@profile_views = ProfileView.select('*').where(:user_id => current_user.id).group(:viewer_id)   

Your query doesn't work because you're using PostgreSQL (or some similarly strict database) and your SELECT list doesn't match your GROUP BY. 您的查询无效,因为您使用的是PostgreSQL(或类似的严格数据库),并且SELECT列表与GROUP BY不匹配。 Everything in your SELECT must either be inside an aggregate function (such as COUNT , AVG , ...) or it must appear in your GROUP BY clause; SELECT中的所有内容都必须在聚合函数中(例如COUNTAVG ,...)或必须出现在GROUP BY子句中; some databases, such as MySQL and SQLite, will take a guess to remove the ambiguity but other databases, such as PostgreSQL, will not. 某些数据库(例如MySQL和SQLite)将猜测消除歧义,而其他数据库(例如PostgreSQL)则不会。 I'd guess that you're seeing an error similar to: 我猜您会看到类似以下的错误:

ERROR:  column "X" must appear in the GROUP BY clause or be used in an aggregate function

You're probably looking for something more like this: 您可能正在寻找更像这样的东西:

@profile_views = ProfileView.where(:user_id => current_user.id)
                            .count(:group => :viewer_id)

That will give you a simple Hash in @profile_views which maps viewer_id (including nil s) to the number of views. 这将在@profile_views为您提供一个简单的Hash,该哈希将viewer_id (包括nil )映射到视图数。

That bit of AR is equivalent to this SQL: AR的那部分等效于以下SQL:

select viewer_id, count(*)
from profile_views
where user_id = #{current_user.id}
group by viewer_id

You'll note that everything in the SELECT is either in the GROUP BY or an aggregate. 您会注意到,SELECT中的所有内容都位于GROUP BY或聚合中。

You can't get the ProfileView objects at the same time as the counts. 您无法与计数同时获得ProfileView对象。 When you add a GROUP BY, you're collapsing rows that have the same viewer_id and once the rows have lost their identities, there is no way for the database to choose which row should be used to instantiate the ProfileView. 添加GROUP BY时,将折叠具有相同viewer_id行,并且一旦这些行失去了标识,数据库将无法选择应使用哪一行来实例化ProfileView。

I do not think you can have select(*) in a group statement. 我认为您不能在group语句中使用select(*) You might try select count(viewer_id) or whatever grouping you are going for. 您可以尝试select count(viewer_id)或要进行的任何分组。

Update 更新

You can see more examples here 您可以在这里看到更多示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM