È appena iniziato l'apprendimento della registrazione attiva e mi sto chiedendo come recuperare i dati da più tabelle in cui è coinvolta una query SQL aggregata.Il record attivo di Rails può gestire query di aggregazione SQL?
Nell'esempio seguente (da un'app medica) cerco gli eventi più recenti di vario tipo per ciascun paziente (ad esempio, l'ultima visita, l'ultimo labtest ecc.). Come puoi vedere dalla query sql qui sotto cerco il valore massimo (data) da una query raggruppata. Ho fatto ricorso a find_by_sql per farlo - tuttavia mi piacerebbe vedere come farlo senza usare find_by_sql.
IOW: come ottenere qui i dati richiesti utilizzando un approccio ActiveRecord puro. Di seguito sono la Tavola e defs Classe sto testando con:
Trova per SQL per recuperare le voci più recenti per ogni tipo - notare la 'max (EVENT_DATE)' qui
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"
Ecco la query di esempio SQL risultato:
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
Classi
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
Seguito rapido qui da OP.Con 1 modifica minore: join (vs: join) Il codice di Ryan funziona e sostituisce la query Find_By_Sql nel mio post originale. Molto bello Tuttavia di passaggio noterò solo che (AFAIK) non tutte le query SQL possono essere implementate tramite chiamate ORM (ad esempio Union Query che combina i valori Min e Max da una tabella). Sospetto che ciò richiederà 2 chiamate separate tramite l'ORM, mentre un Find_By_Sql può farlo in una chiamata, ad es. find_by_sql ("Seleziona Min (t.Event_Date) dalla tabella t Unione Seleziona Max (t.Event_Date) dalla tabella t") – BrendanC
Aggiornato il post originale da utilizzare: join. Sei corretto, tuttavia, non tutte le query possono essere eseguite con ORM, e questo non è l'obiettivo di Active Record. È stato progettato appositamente per soddisfare la maggior parte dei bisogni e lasciare il resto possibile con find_by_sql. Non cerca di fare tutto, quindi non esitate a usare find_by_sql se si adatta meglio al lavoro. – ryanb