我有一个具有多个间隔的房间模型。 Intervals具有start_date和end_date属性。我想根据以下条件订购客房
1-没有间隔的房间 2-房间,任何间隔,start_date> Date.today 没有任何间隔的3-房间,带有start_date> Date.tody
我想以这样的方式对房间进行排序:满足1的房间首先出现,然后使用postgresql查询而不是模型上的方法满足2然后3房间。
虽然使用下面的查询/范围找出哪些房间没有间隔没有问题
joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").where("intervals.id is NULL")
我在单个查询中遇到3个条件的排序问题,我尝试了以下
Room.joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").order("CASE WHEN intervals.id IS NULL THEN 1 END ASC")
此查询的问题在于,如果您在其上调用distinct,则会收到错误PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
,另一个问题即使您在此处调用distinct并且它正常工作,您只能按一个条件进行排序第1步。
我的想法是使用case条件生成一个函数,根据3个条件给出生成列的值,并给第一个值1,第二个值2和第三个值3,并按此计算值排序,每当我尝试它时,我会被上面提到的错误击中。任何帮助将不胜感激。
这是我结合所有3个条件的试验:
Room.joins("LEFT OUTER JOIN intervals ON rooms.id = intervals.room_id").group("room.id").order("CASE WHEN room.id IS NULL THEN 1 WHEN COUNT(CASE WHEN intervals.start_date > '#{Date.today.to_s(:db)}' THEN 1 END) > 0 THEN 2 WHEN COUNT(CASE WHEN intervals.start_date > '#{Date.today.to_s(:db)}' THEN 1 END) = 0 THEN 3 END")
然而,这会给出错误:PG :: GroupingError:ERROR:列“intervals.id”必须出现在GROUP BY子句中或用于聚合函数
任何帮助都将不胜感激。
答案 0 :(得分:1)
在此"具体"例如,我会针对您的特定业务规则对模式进行去规范化。请记住,您可能需要在某些时候进行分页,并且需要在db进行排序。
为此,我会在模型中添加一列以指示排序优先级:
add_column :rooms, :sort_priority, :integer, null: false, default: 0
然后在我的间隔模型中,我将包含一个设置优先级
的before_save过滤器before_save -> {
if (start_date < blah blah blah)
self.priority = 1
elsif (blah blah)
etc...
end
}
然后我会在我的参考文献中反映这一点
class Room
has_many :intervals, -> {order :priority, :start_date}
end