我有一个包含作业列表的表,显示时通常按created_at字段降序排序。我正在添加一个“特色”布尔标志,这将增加客户能够更好地了解其工作列表的能力。如果作业少于X天,我希望将精选列表固定在搜索结果的顶部。如何通过现有查询进行修改以支持此功能?
Jobs.where("expiration_date >= ? and published = ?", Date.today, true).order("created_at DESC")
当前查询将拉回由created_at命令的所有当前已发布作业。
答案 0 :(得分:3)
与其他一些数据库(如Oracle)不同,PostgreSQL具有功能齐全的boolean
类型。您可以在ORDER BY
子句中直接使用 而不应用CASE
语句 - 这些对于更复杂的情况非常有用。
boolean
值的排序顺序为:
FALSE -> TRUE -> NULL
如果您ORDER BY bool_expression
DESC
,则将订单反转为:
NULL -> TRUE -> FALSE
如果您希望TRUE
先行,NULL
持续,请使用NULLS LAST
clause of ORDER BY
:
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'
在第一个示例中,右侧的表达式是计算一次的常量。然后可以使用索引来查找匹配的行。很有效率。
后者通常不能与索引一起使用。必须为每一行计算一个值,然后才能根据右边的常量表达式检查它。如果可以避免,请不要这样做。永远!
答案 1 :(得分:0)
不确定你想在这里实现什么。
我猜你会对结果进行分页。如果是这样,并且您希望始终在顶部显示特色作业,而不管页面如何,则应分别从DB中提取它们。如果您只想在第一页上显示它们,请按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