J'ai commencé à apprendre l'enregistrement actif et je me demande comment récupérer au mieux les données de plusieurs tables où une requête d'agrégat SQL est impliquée.L'enregistrement actif de Can Rails gère les requêtes d'agrégat SQL?
Dans l'exemple suivant (d'une application médicale), je suis à la recherche des événements les plus récents de divers types pour chaque patient (par exemple, dernière visite, dernier test, etc.). Comme vous pouvez le voir dans la requête sql ci-dessous, je suis à la recherche de la valeur max (date) d'une requête groupée. J'ai eu recours à find_by_sql pour le faire - mais j'aimerais voir comment faire ceci sans utiliser find_by_sql. IOW - comment obtiendriez-vous les données requises ici en utilisant une approche ActiveRecord pure. Ci-dessous sont la table et defs classe je teste avec:
Recherche par Sql pour récupérer les plus récentes entrées pour chaque type - notez le « max (EVENT_DATE) » ici
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"
Voici l'exemple de requête SQL résultat:
lname, patient_id, event_type, latest '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' Table Relationships are: Tables ---> Patients --> Events --> visits --> labtests --> ... other patients t.string :lname t.date :dob events t.column :patient_id, :integer t.column :event_date, :datetime t.column :event_type, :string visits t.column :event_id, :integer t.column :visittype, :string labtests t.column :event_id, :integer t.column :testtype, :string t.column :testvalue, :string
Classes
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
Suivi rapide ici d'OP.Avec 1 tweak mineur: joint (vs: join) Le code de Ryan fonctionne et remplace la requête Find_By_Sql dans mon post original. Très sympa. Cependant, en passant, je noterai simplement (AFAIK) que toutes les requêtes SQL ne peuvent pas être implémentées via des appels ORM (par exemple Union Query qui combine les valeurs Min et Max d'une table). Je suppose que cela nécessitera 2 appels distincts via l'ORM, tandis qu'un Find_By_Sql peut le faire dans 1 appel par exemple. find_by_sql ("Select Min (t.Event_Date) de la table t Union Select Max (t.Event_Date) de la table t") – BrendanC
Mise à jour du message d'origine à utiliser: jointures. Vous avez raison cependant, toutes les requêtes ne peuvent pas être effectuées avec l'ORM, et ce n'est pas l'objectif de Active Record. Il a été conçu pour répondre à la majorité des besoins et laisser le reste possible avec find_by_sql. Il n'essaie pas de tout faire, alors n'hésitez pas à utiliser find_by_sql si cela correspond mieux au travail. – ryanb