Ruby on rails Rails和ActiveRecord:困难的SQL查询
在我的Rails应用程序中,我允许用户对事件进行投票。有些活动仅为一个特定日期,有些活动正在进行中 我正在尝试构建一个查询,以呈现用户未投票的所有事件或用户在1个月前投票的正在进行的事件 事件有一个正在进行的布尔列。这项活动获得了许多选票。而且用户有很多投票权 下面是我的查询,以获取用户未投票的所有事件。它起作用了Ruby on rails Rails和ActiveRecord:困难的SQL查询,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,在我的Rails应用程序中,我允许用户对事件进行投票。有些活动仅为一个特定日期,有些活动正在进行中 我正在尝试构建一个查询,以呈现用户未投票的所有事件或用户在1个月前投票的正在进行的事件 事件有一个正在进行的布尔列。这项活动获得了许多选票。而且用户有很多投票权 下面是我的查询,以获取用户未投票的所有事件。它起作用了 scope :unvoted, ->(user_id) { joins( "LEFT OUTER JOIN votes ON votes.event_
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).where("votes.id IS NULL")
}
我正在尝试添加或部分查询。我需要包括用户在一个多月前投票的正在进行的事件。以下是我尝试过的:
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
)
.where(
"votes.id IS NULL OR events.ongoing = ? AND MAX(votes.created_at) < ?", true, 1.month.ago
)
}
但这给了我一个错误:
PG::GroupingError:错误:其中不允许使用聚合函数
所以我试了一下:
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).
having('votes.id IS NULL OR events.ongoing = ? AND MAX("votes"."created_at") < ?', true, 1.month.ago).
group("events.id")
}
但这给了我一个错误:
错误:列必须出现在GROUP BY子句中或在聚合函数中使用
我要查找的正确查询是什么?编辑:
似乎没有写作的方式,也没有拥有的方式。您可以使用子查询或联合来解决此问题
或者为了保持简单,您可以将其分为两个查询
只有ActiveRecord解决方案:可以尝试吗
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).where(
"votes.id IS NULL OR events.ongoing = ?", true
).select('events.*, MAX(votes.created_at) as created_at')
).group('events.id')
}
然后在你的方法中,你可以
对于复杂的SQL问题,请选择{| e | e.created_at<1.month.ago},确保用RDBMS标记它们,并创建一个表和预期结果的良好示例。例如,postgres和mysql标签的关注者比RubyonRails多得多,你往往会得到更好的答案。你使用MAX的目的是什么?只是从匹配的记录中获取最新的记录,或者从新到旧订购记录?@YTorii我需要从匹配的记录中获取最新的记录,以查看它是否是在一个月前创建的。您可能希望将第二个记录表示为上个月内未对用户投票的正在进行的事件。在SQL术语中,一个简单的不存在的相关子查询,或者如果您想走这条路线,可能是一个外部联接。Hmmm。。我不确定这是否有效,因为它将返回所有事件,并且投票时间早于1个月前。但我只想回顾最近投票超过一个月的事件ago@JacksonCunningham好的,意识到了。你能提供一个用两个查询来实现这一点的例子吗?我喜欢这种方法,但不知道如何使用或