Can Rails' Active Record handle SQL aggregate queries?

前端 未结 3 1295
孤独总比滥情好
孤独总比滥情好 2021-02-02 02:33

Just started learning active record and am wondering how to best retrieve data from multiple tables where an SQL aggregate query is involved.

In the following example (f

相关标签:
3条回答
  • 2021-02-02 03:24

    An include is just a clever left join, you can use that in conjuction with select and group_by in your .find

    0 讨论(0)
  • 2021-02-02 03:24

    In the current version of AR (2.3) I think your only option is to use find_by_sql. Why? Your custom SELECT attributes. ActiveRecord allows :select and :include arguments to the find call. Unfortunately they can't be used together. If you specify both the :select will be ignored. In your example you need the select to limit your columns and to get your MAX function.

    I've heard there is a patch/hack to get them to work together, but I am not sure where it is.

    Peer

    0 讨论(0)
  • 2021-02-02 03:26

    As Pallan pointed out, the :select option cannot be used with the :include option. However the :joins option can. And this is what you want here. In fact, it can take the same arguments as :include or use your own SQL. Here's some rough, untested code, may need some minor fiddling.

    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")
    

    Note I modified things slightly. I renamed the event_date alias to max_date so there's no confusion over which attribute you are referring to. The attributes used in your :select query are available in the models returned. For example, in this you can call event.max_date. I also added the event id column because you can sometimes get some nasty errors without an id attribute (depending on how you use the returned models).

    The primary difference between :include and :joins is that the former performs eager loading of the associated models. In other words, it will automatically fetch the associated patient object for each event. This requires control of the select statement because it needs to select the patient attributes at the same time. With :joins the patient objects are not instantiated.

    0 讨论(0)
提交回复
热议问题