小编典典

Rails的Active Record可以处理SQL聚合查询吗?

sql

刚刚开始学习活动记录,并且想知道如何最好地从涉及SQL聚合查询的多个表中检索数据。

在以下示例(来自医疗应用程序)中,我正在寻找每个患者的各种类型的最新事件(例如,上次就诊,上次实验室检查等)。从下面的sql查询中可以看到,我正在从分组查询中查找max(date)值。我求助于find_by_sql来执行此操作-
但是我想看看如何在不使用find_by_sql的情况下执行此操作。

IOW-您将如何使用纯ActiveRecord方法在此处获取所需数据。以下是我正在测试的Table和Class def:

通过Sql查找以检索每种类型的最新条目-在此处注意’max(event_date)’

strsql = "select  p.lname, e.patient_id, e.event_type, max(e.event_date) as event_date 
     from events e   
         inner join patients p on e.patient_id = p.id
         group by p.lname, e.patient_id, e.event_type"

这是示例SQL查询结果:

lname,Patient_ID,event_type,最新
'Hunt',3,'Labtest','2003-05-01 00:00:00'
'Hunt',3,'Visit','2003-03-01 00:00:00'
'Seifer',2,'Labtest','2002-05-01 00:00:00'
'Seifer',2,'Visit','2002-03-01 00:00:00'

表关系是:
表格--->患者->事件
                               ->访问
                               ->实验室测试
                               -> ...其他
耐心
      t.string:lname
      日期:dob

大事记
      t.column:patient_id,:integer
      t.column:event_date,:datetime
      t.column:event_type,:string

造访 
      t.column:event_id,:integer
      t.column:visittype,:string

实验室测试
      t.column:event_id,:integer
      t.column:testtype,:string
      t.column:testvalue,:string

班级

class Patient < ActiveRecord::Base
  has_many :events
  has_many :visits, :through =>:events
  has_many :labtests, :through => :events
end

class Event < ActiveRecord::Base
  has_many :visits
  has_many :labtests
  belongs_to :patient
end

class Visit < ActiveRecord::Base
  belongs_to :event
end

class Labtest < ActiveRecord::Base
    belongs_to :event
end

阅读 223

收藏
2021-04-15

共1个答案

小编典典

正如Pallan指出的那样,该:select选项不能与该:include选项一起使用。但是该:joins选项可以。这就是您想要的。实际上,它可以使用相同的参数,也可以:include使用自己的SQL。这是一些未经测试的粗略代码,可能需要一些小摆弄。

Event.all(:select => "events.id, patients.lname, events.patient_id, events.event_type, max(events.event_date) as max_date", :joins => :patient, :group => "patients.lname, events.patient_id, events.event_type")

注意,我对内容进行了一些修改。我将event_date别名重命名为,max_date因此不会混淆您所指的是哪个属性。:select查询中使用的属性在返回的模型中可用。例如,在此您可以调用event.max_date。我还添加了事件id列,因为有时您可能会遇到一些讨厌的错误而没有id属性(取决于您使用返回的模型的方式)。

:include和之间的主要区别在于,:joins前者执行相关模型的热切加载。换句话说,它将为每个事件自动获取关联的患者对象。这需要控制select语句,因为它需要同时选择患者属性。带有:joins病人对象没有被实例化。

2021-04-15