Ruby on rails 使用Rails构造查询-组、最大值、并集

Ruby on rails 使用Rails构造查询-组、最大值、并集,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有两种型号: 学生 ->有很多:注册 招生 ->属于:学生 表格是这样的: 现在,我的目标是检索那些最近的注册结束日期小于当前日期的学生,或者如果该学生尚未注册。因此,鉴于上面链接上的示例表,且当前日期为2019年11月20日,查询应返回: John Doe(因为最新结束日期为2019年1月11日,比2019年11月20日小) Casper Gost(因为该学生还没有入学记录) 如何在RubyonRails中创建该查询?(对不起,我还是rails的noob) 我认为sql查询如下所示

我有两种型号:

  • 学生 ->有很多:注册
  • 招生 ->属于:学生
表格是这样的:

现在,我的目标是检索那些最近的注册结束日期小于当前日期的学生,或者如果该学生尚未注册。因此,鉴于上面链接上的示例表,且当前日期为2019年11月20日,查询应返回:

  • John Doe(因为最新结束日期为2019年1月11日,比2019年11月20日小)
  • Casper Gost(因为该学生还没有入学记录)
如何在RubyonRails中创建该查询?(对不起,我还是rails的noob)

我认为sql查询如下所示:

select students.*
from students s
left join
( select student_id, end_date 
  from enrollments e1
  where end_date = (select max(e2.end_date) 
                    from enrollments e2 
                    group by e2.student_id 
                    having e2.student_id = e1.student_id
                    )
) e on e.student_id = s.id
where e.end_date < Date.today OR e.student_id IS NULL
报名模式:

scope :no_enrollments, -> { where.not(id: Enrollment.pluck(:student_id)) }
scope :with_expired_enrollments, -> { joins(:enrollments).merge(Enrollment.expired_enrollments) }
scope :unenrolled, -> { find_by_sql("#{no_enrollments.to_sql} UNION #{with_expired_enrollments.to_sql}") }
scope :expired_enrollments, -> { where('end_date IN (?)',Enrollment.all.group(:student_id).maximum(:end_date).values).where('end_date < ?', Date.today) }
也许不是最佳解决方案,但它在我的应用程序上有效。谢谢@nathanvda和@Catmal。

试试这个:

@selected_students = Student.where.not(
  id: Enrollment.pluck(:student_id)
).or(
  Student.includes(:enrollments).where(
    enrollments: {
      date_end < Date.today
    }
  )
)
@selected\u students=Student.where.not(
id:Enrollment.Pull(:student\u id)
).或(
学生。包括(:注册)。在哪里(
报名人数:{
日期\结束<今天的日期
}
)
)

对于这样的情况,我更喜欢使用
按sql查找:您的查询是一个非常特殊的情况,非常有效,imho,我不知道如何在ActiveRecord中复制,也不确定这是否真的值得。我尝试了您的解决方案,但“或”方法给出了一个不兼容的错误:(传递给#的关系或必须在结构上兼容。不兼容的值:[:包括])此外,我稍微修改了代码以满足我的需要:Student.where.not(id:Enrollment.Pulk(:Student_id))Student.joins(:enrollments)。where('end_date IN(?)、Enrollment.all.group(:Student_id)。最大值(:end_date)。where('end_date<?',date.today)第一个查询获取注册中没有记录的所有学生,第二个查询获取最后一个结束日期
@selected_students = Student.where.not(
  id: Enrollment.pluck(:student_id)
).or(
  Student.includes(:enrollments).where(
    enrollments: {
      date_end < Date.today
    }
  )
)