![](/img/trans.png)
[英]Not sure how to write a query to return column associated with max value in group by
[英]Rails query for associated model with max column value
我有3種模型:Author,Book和Page。 頁面屬於書籍,書籍屬於作者,因此:
class Author < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
belongs_to :author
has_many :pages
end
class Page < ActiveRecord::Base
belongs_to :book
end
Page模型有一個稱為page_number的列。 我正在使用Postgres。
我的問題是:假設有一個作者@author
,如何查詢該作者的所有最后一頁? 換句話說,我想要那個作者寫的每本書的最后一頁。 我正在嘗試以下不起作用的方法:
Page.where(book_id: @author.books.pluck(:id)).select('MAX(page_number), *').group(:book_id)
編輯
以下兩行有效,但我很想學習更快/更清潔的解決方案:
all_pages = Page.where(book: @author.books)
last_pages = all_pages.select{ |a| !all_pages.select{ |b| b.book_id == a.book_id}.any?{ |c| c.page_number > a.page_number } }
最有效的方法可能是利用postgres的窗口功能
這樣的查詢不適合activerecord的通用用例,因此您可能必須使用find_by_sql
,但這很值得。
在您的情況下,最好先獲取圖書ID,因為加入或進行其他子查詢可能沒有優勢-您的電話。
假設您有@author.books.ids
中的書籍ID列表。 我們想要的下一件事情是一本書的“分組依據”頁面列表,因此我們可以為每個組提取最后一頁。 令1,2為有關作者的書號。
我們可以在postgres中使用window函數和rank
函數來創建一個結果集,其中頁面在書的分區(組)上排名。 我們甚至將這些分區按頁碼排序,以便最大頁碼(最后一頁)位於每個分區的頂部。 查詢如下所示:
select
*,
rank() over (
partition by book_id order by page_number desc
) as reverse_page_index
from pages
where book_id in (1,2)
我們想象的pages
結果集將如下所示。
author 1, book 1, page 3, rank 1
author 1, book 1, page 2, rank 2
author 1, book 1, page 1, rank 3
author 1, book 2, page 6, rank 1
author 1, book 2, page 5, rank 2
author 1, book 2, page 4, rank 3
author 1, book 2, page 3, rank 4
author 1, book 2, page 2, rank 5
author 1, book 2, page 1, rank 6
頁面記錄按書分區,按頁碼升序排序,並在其分區中排名。
如果在執行窗口計算之后 ,如果只希望每本書排名第一(最后一頁),則可以使用子選擇,如下所示:
select *
from
(
select
*,
rank() over (
partition by book_id order by page_number desc
) as reverse_page_index
from pages
where book_id in (1,2)
) as pages
where reverse_page_index = 1;
我們將上面想象的結果集過濾到僅排名(reverse_page_index)為1(即最后一頁)的頁面記錄中。
現在我們的結果集將是:
author 1, book 1, page 3, rank 1
author 1, book 2, page 6, rank 1
您還可以按最后修改日期或您需要的順序訂購此結果集。
在find_by_sql
該查詢,您將有一些activerecord對象要使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.