繁体   English   中英

Rails 查询按单个关联行列对记录进行排序

[英]Rails query to order records by single association row column

假设我有一个 books 表,其中包含 id 和 name 列以及 has_many book_ratings 关联。 book_ratings 表有 id、rating、rating_date 和 book_id 列以及 belongs_to:book。 我在一个包含 3 列的表格中显示书籍:书籍名称、书籍的最高评分和书籍的最新评分。 我希望每一列都可以排序,并且我正在使用 Pagy gem 进行分页。 我想对每个表进行一次调用以避免 N+1。

我做了这个查询,其中包括 max_rating 并按 max_rating 排序:

@pagy, @books = pagy(
  Book.joins(:book_ratings)
      .select('books.*,MAX(rating) as max_rating')
      .order('max_rating')
      .group('books.id')
)

对于每本书记录,我可以调用 book.max_rating 以在表中显示 max_rating。 我想不出一种方法来包含最新日期的评级并按该评级对记录进行排序。 我知道我可以使用MAX(rating_date)来获取最新日期的 book_rating 日期,但我需要一种方法来包含最新日期的 book_rating 的评级值,并且还能够通过那些来订购图书记录值。

有任何想法吗?

为了让它工作,我最终使用了 select 方法,然后链接了两个连接方法。 这是我最终使用的:

Book.select('books.*,t2.rating as latest_rating,t4.rating as highest_rating')
    .joins(
      "INNER JOIN (
         SELECT book_ratings.rating, book_ratings.book_id, book_ratings.rating_date
         FROM book_ratings
         JOIN (
           SELECT book_id, MAX(rating_date) as max_date
           FROM book_ratings GROUP BY book_id
         ) t1
         ON t1.book_id = book_ratings.book_id
         AND t1.max_date = book_ratings.rating_date
       ) t2
       ON t2.book_id = books.id"
    )
    .joins(
      "INNER JOIN (
         SELECT book_ratings.rating, book_ratings.book_id
         FROM book_ratings
         JOIN (
           SELECT book_id, MAX(rating) as max_rating
           FROM book_ratings
           GROUP BY book_id
         ) t3
         ON t3.book_id = book_ratings.book_id
         AND t3.max_rating = book_ratings.rating
       ) t4
       ON t4.book_id = books.id"
    )
    .distinct

在该查询上调用.to_sql得到这个 SQL:

SELECT DISTINCT books.*,t2.rating as latest_rating,t4.rating as highest_rating
FROM "books"
INNER JOIN (
  SELECT book_ratings.rating, book_ratings.book_id, book_ratings.date
  FROM book_ratings
  JOIN (
    SELECT book_id, MAX(date) as max_date
    FROM book_ratings
    GROUP BY book_id
  ) t1
  ON t1.book_id = book_ratings.book_id
  AND t1.max_date = book_ratings.date
) t2
ON t2.book_id = books.id
INNER JOIN (
  SELECT book_ratings.rating, book_ratings.book_id
  FROM book_ratings
  JOIN (
    SELECT book_id, MAX(rating) as max_rating
    FROM book_ratings
    GROUP BY book_id
  ) t3
  ON t3.book_id = book_ratings.book_id
  AND t3.max_rating = book_ratings.rating
) t4
ON t4.book_id = books.id

遍历此集合时,可以在每个 object 上调用 latest_rating 和 highest_rating 并提供来自评级列的值。 它也可以与.order('latest_rating asc') (或 desc)或.order('highest_rating asc') (或 desc)一起使用

暂无
暂无

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

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