刚刚开始学习活动记录,并且想知道如何最好地从涉及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
正如Pallan指出的那样,该:select选项不能与该:include选项一起使用。但是该:joins选项可以。这就是您想要的。实际上,它可以使用相同的参数,也可以:include使用自己的SQL。这是一些未经测试的粗略代码,可能需要一些小摆弄。
:select
:include
:joins
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属性(取决于您使用返回的模型的方式)。
event_date
max_date
event.max_date
id
:include和之间的主要区别在于,:joins前者执行相关模型的热切加载。换句话说,它将为每个事件自动获取关联的患者对象。这需要控制select语句,因为它需要同时选择患者属性。带有:joins病人对象没有被实例化。
select