activerecord中最近的内部查询

dba5bblo  于 2021-08-13  发布在  Java
关注(0)|答案(1)|浏览(350)

我有一张table users :

id  first_name
--------------
1   Bill
2   Denise

谁读过多本书 books :

id  book                       user_id  read_at
---------------------------------------------------
1   Garry Potter               1        2020-1-1
2   Lord of the wrist watch    2        2020-1-1
3   90 Shades of navy          2        2020-1-2

我想在我的 book 为每个用户提供最新书籍的模型。在纯sql中有很多这样做的例子,我运行的问题是创建一个灵活的作用域,它可以与计数、内部查询或其他通常使用作用域的方式一起使用。
到目前为止,我已经有了这个 book 型号:

def self.most_recent
  inner_query = select('DISTINCT ON (user_id) *').order(:user_id, read_at: :desc)
  select('*').from(inner_query, :inner_query).order('inner_query.id')
end

非常接近我想要的。它与计数一起工作,但在更复杂的情况下不起作用。
例如,如果我想得到一个用户列表,他们最新的书是“加里·波特”,我可以这样做:

User.where(id: Book.most_recent.where(book: 'Garry Potter').select(:user_id))

活动记录混淆并生成以下sql:

SELECT "users".* FROM "users" WHERE "users"."id" IN (SELECT "user_id", * FROM (SELECT "books"."user_id", DISTINCT ON (user_id) * FROM "books" ORDER BY "books"."user_id" ASC, "books"."read_at" DESC) inner_query WHERE "books"."book" = "Garry Potter" ORDER BY inner_query.id)

从而产生以下错误:

ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:  syntax error at or near "DISTINCT"

有没有一个优雅的方法来实现这一点?

xxslljrj

xxslljrj1#

你可以试着改变方法 most_recent 通过返回查询 where :

def self.most_recent
  # Select only the ids of the most recent books
  inner_query = select('DISTINCT ON (user_id) books.id').order(:user_id, read_at: :desc)

  # Return a where query like Book.where(id: <ids in the result set of the query above>)
  where(id: inner_query)
end

# You should now be able to perform the following query

User.where(
  id: Book.most_recent.where(book: 'Garry Potter').select(:user_id)
)

相关问题