[英]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 BY
的NULLS LAST
子句:
ORDER BY (featured AND created_at > now() - interval '11 days') DESC NULLS LAST
, created_at DESC
當然, NULLS LAST
只有當相關featured
或created_at
可NULL
。 如果列被定義為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.