![](/img/trans.png)
[英]Rails 4 ActiveRecord query join and order by a user's number of association records
[英]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.