49

我有一个简单的查询需求:查找自 2013 年 1 月 1 日以来下订单的用户列表。

在 SQL 中,这是一个非常简单的查询。

但我正在使用 Rails 和 Active Record。

所以我写道:User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'")

在我们的数据库中,自 2013 年 1 月 1 日以来,我们有 75 个用户发出的 100 个订单。(有些用户显然下了不止一份订单。)

但是,上面的表达式返回 100 个用户。(必须有重复。)

我试过了User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'").uniq

那也行不通。

如何获取自 2013 年 1 月 1 日起下订单的 75 位用户?

4

4 回答 4

73

@dbjohn 有正确的想法,但我假设您想避免创建额外的对象。这是他的解决方案的一个小变种,让数据库为您执行唯一操作:

date = "2013-01-01 00:00:00"
User.joins(:orders).where("orders.created_at >= ?", date).distinct

请注意,您可以重新排列方法的顺序以适合您认为最符合语义的任何内容,ActiveRecord 将为您编写相同的 SQL。

于 2014-04-25T21:05:06.800 回答
16
User.joins(:orders).
    where("orders.created_at >= '2013-01-01 00:00:00'").
    group('users.id')

group方法将链接到查询并为您提供唯一记录列表。

于 2014-08-07T20:59:05.150 回答
1

您可以像这样编写嵌套查询:

User.where(id: User.joins(:orders).where("orders.created_at >= '2013-01-01 00:00:00'").ids)

于 2021-12-11T17:31:11.457 回答
-4

Railsuniq从 3.2.1 版开始添加,所以现在你可以使用uniq

http://apidock.com/rails/ActiveRecord/QueryMethods/uniq

于 2015-11-10T11:55:16.980 回答