簡體   English   中英

Active Record Query中基於時間的優先級

[英]Time based priority in Active Record Query

我有一個包含工作列表的表,顯示時通常按 created_at 字段降序排序。 我正在添加一個“特色”布爾標志,這將使客戶能夠更多地了解他們的工作列表。 如果工作不到 X 天,我希望將特色列表固定在搜索結果的頂部。 我將如何通過現有查詢進行修改以支持這一點?

Jobs.where("expiration_date >= ? and published = ?", Date.today, true).order("created_at DESC") 

當前查詢拉回所有當前已發布的作業,按 created_at 排序。

與其他一些數據庫(如 Oracle)不同,PostgreSQL 具有功能齊全的boolean類型。 您可以直接ORDER BY子句中使用它,而無需應用CASE語句 - 這對於更復雜的情況非常有用。

boolean值的排序順序是:

FALSE -> TRUE -> NULL

如果您ORDER BY bool_expression DESC ,則將順序反轉為:

NULL -> TRUE -> FALSE

如果您首先想要TRUE ,最后想要NULL ,請使用ORDER BYNULLS LAST子句

ORDER BY (featured AND created_at > now() - interval '11 days') DESC NULLS LAST  
       , created_at DESC

當然, NULLS LAST只有當相關featuredcreated_atNULL 如果列被定義為NOT NULL ,那么不要打擾。

此外, FALSE將排在NULL之前。 如果你不想區分這兩者,你要么回到CASE語句,要么你可以拋出NULLIF()COALESCE()

ORDER BY NULLIF(featured AND created_at > now() - interval '11 days'), FALSE)
                                                                DESC NULLS LAST
       , created_at DESC

表現

注意,我是如何使用的:

created_at > now() - interval '11 days'

不是

now() - created_at < interval '11 days'

在第一個例子中,右邊的表達式是一個計算一次的常數。 然后可以使用索引來查找匹配的行。 非常有效率。

后者通常不能與索引一起使用。 必須為每一行計算一個值,然后才能根據右側的常量表達式進行檢查。 如果可以避免,請不要這樣做。 曾經!

不確定你想在這里實現什么。

我想你會對結果進行分頁。 如果是這樣,並且您希望始終在頂部顯示特色作業,而不管頁面如何,那么您應該單獨從數據庫中提取它們。 如果您只想在第一頁上顯示它們,請按以下方式published

Jobs.where("expiration_date >= ?", Date.today).order("published DESC, created_at DESC") 

如果你想分別拉動它們:

@featured_jobs = Jobs.where("expiration_date >= ? and published = ?", Date.today, true).order("created_at DESC")
@regular_jobs = Jobs.where("expiration_date >= ? AND published = ?", Date.today, false).order("created_at DESC") #Paginate them too ... depends on the gem you're using

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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