簡體   English   中英

Rails查詢關聯模型的最大列值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM