我有一个使用ActiveRecord和Postgresql的Rails 4应用程序,有两个表:stores
和open_hours
。 store
有许多open_hours
:
存储
Column |
--------------------+
id |
name |
OPEN_HOURS:
Column |
-----------------+
id |
open_time |
close_time |
store_id |
open_time
和close_time
列表示自星期日午夜(即星期一开始)以来的秒数。
我想获得商店是否开放的store
对象列表,因此打开的商店将排在已关闭的商店之前。这是我在Rails中的查询:
Store.joins(:open_hours).order("#{current_time} > open_time AND #{current_time} < close_time desc")
注意current_time
是自上周日午夜以来的秒数。
这给了我一个商店列表,其中当前开放的商店排在封闭商店之前。但是,我在结果中得到了很多重复。
我尝试使用distinct,uniq和group方法,但它们都不起作用:
Store.joins(:open_hours).group("stores.id").group("open_hours.open_time").group("open_hours.close_time").order("#{current_time} > open_time AND #{current_time} < close_time desc")
我已经在Stackoverflow上阅读了很多问题/答案,但大多数人都没有解决order
方法问题。 This question似乎是最相关的,但MAX
聚合函数不适用于布尔值。
非常感谢任何帮助!感谢。
答案 0 :(得分:1)
以下是我为解决问题所做的工作:
在Rails中:
is_open = "bool_or(#{current_time} > open_time AND #{current_time} < close_time)"
Store.select("stores.*, CASE WHEN #{is_open} THEN 1 WHEN #{is_open} IS NULL THEN 2 ELSE 3 END AS open").group("stores.id").joins("LEFT JOIN open_hours ON open_hours.store_id = stores.id").uniq.order("open asc")
说明:
is_open
变量用于缩短select
语句。 bool_or
聚合函数来对open_hours
条记录进行分组。否则,每个商店可能会有两个结果(一个打开,一个关闭),这就是为什么单独使用uniq
方法不能消除重复的问题LEFT JOIN
代替INNER JOIN
,因此我们可以包含没有任何open_hours
个对象的商店CASE WHEN
将首先显示打开商店,然后是未确定商店,然后是已关闭商店。< / LI>
此解决方案有效,但感觉不是很优雅。如果您有更好的解决方案,请发布您的答案。非常感谢!
答案 1 :(得分:0)
您是否尝试过uniq
方法,只需将其附加到最后
Store.joins(:open_hours).order("#{current_time} > open_time AND #{current_time} < close_time desc").uniq