使用ActiveRecord查询界面进行分组和排序

时间:2019-05-27 14:04:49

标签: ruby-on-rails postgresql activerecord

我有一个模型ConnectedUser,它属于另外两个模型UserStation

这是具有这些关系和布尔值active的简单模型。

我针对的查询结果将仅为每个ConnectedUser(其中User是特定ID)的每个最新Station记录。

例如,如果我的ConnectedUser表看起来像这样……

+----+---------+------------+--------+------------+
| id | user_id | station_id | active | created_at |
+----+---------+------------+--------+------------+
|  1 |       1 |          1 | true   | 20 June    |
|  2 |       1 |          1 | false  | 19 June    |
|  3 |       1 |          2 | false  | 20 June    |
|  4 |       2 |          1 | false  | 18 June    |
|  5 |       2 |          1 | false  | 21 June    |
+----+---------+------------+--------+------------+

那个车站是ID为1的那个车站,那么我想查询返回...

[
<ConnectedUser id: 1, user_id: 1, station_id: 1, active: true, created_at: "2019-06-20">,
<ConnectedUser id: 5, user_id: 2, station_id: 1, active: false, created_at: "2019-06-21">
]

为此,我一直尝试使用grouporder

ConnectedUser.where(station: station).select(:user_id).group(:user_id).order(:created_at)

但是一直出现这样的错误:

  

ActiveRecord :: StatementInvalid(PG :: GroupingError:ERROR:列   “ connected_users.created_at”必须出现在GROUP BY子句中或   在聚合函数中使用)

我无法获取具体的ConnectedUser ID,因此感觉好像缺少一些重要的知识来了解如何使用group和汇总结果。

在一个ActiveRecord查询中有可能吗?

非常感谢。

3 个答案:

答案 0 :(得分:1)

在Postgres中,如果您想要每个用户/工作站的最新版本,我建议使用distinct on

select distinct on (station_id, user_id) cu.*
from ConnectedUser cu
order by station_id, user_id, created_at desc;

答案 1 :(得分:1)

您应该使用DISTINCT ON而不是GROUP。您可以在Rails中执行以下操作:

ConnectedUser.select("DISTINCT ON (station_id, user_id) *")
             .where(station_id: params[:station_id])
             .order(created_at: :desc)

当然要过滤params[:station_id]

答案 2 :(得分:0)

可能,这可以解决

ConnectedUser.where(active: true).order(user_id: :desc).uniq(&:user_id)

order用于对user_id中的DESC字段进行排序

在此解决方案上,我正在使用uniq,这是一个数组解决方案,它将仅选择最新的user_id

编辑:

我错了,uniq没有按预期工作,但是在这里进行测试后,我发现:

ConnectedUser.where(active: true).order(created_at: :desc).group(:user_id)

似乎很像您,但是,当您使用select时,它只会选择字段user_id,因此,您无法按created_at

进行订购

应该工作