我有一个模型ConnectedUser
,它属于另外两个模型User
和Station
。
这是具有这些关系和布尔值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">
]
为此,我一直尝试使用group
和order
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查询中有可能吗?
非常感谢。
答案 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
应该工作