Właśnie zacząłem uczyć się aktywnego zapisu i zastanawiam się, jak najlepiej pobrać dane z wielu tabel, w które zaangażowane jest zapytanie agregujące SQL.Czy rekord aktywny Active Rails obsługuje zapytania agregacyjne SQL?
W poniższym przykładzie (z aplikacji medycznej) szukam najnowszych zdarzeń różnych typów dla każdego pacjenta (np. Ostatniej wizyty, ostatniego testu laboratoryjnego itp.). Jak widać z poniższego zapytania sql szukam wartości max (date) z kwerendy zgrupowanej. W tym celu uciekłem się do find_by_sql - jednak chciałbym zobaczyć, jak to zrobić bez użycia find_by_sql.
IOW - w jaki sposób uzyskałbyś wymagane dane tutaj, używając czystego podejścia ActiveRecord. Poniżej znajduje się tabela i defs Klasa I 'm testowania z:
znaleźć, SQL, aby pobrać najnowsze dane dla każdego typu - zwrócić uwagę na „max (EVENT_DATE)” tutaj
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"
Oto przykładowe zapytanie sql wynik:
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
Klasy
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
Szybkie śledzenie tutaj z OP.Z 1 drobnym usprawnieniem: join (vs: join) kod Ryana działa i zastępuje zapytanie Find_By_Sql w moim oryginalnym wpisie. Bardzo fajny. Jednak na marginesie zauważę tylko, że (AFAIK) nie wszystkie kwerendy SQL mogą być implementowane za pośrednictwem wywołań ORM (na przykład unijne zapytanie, które łączy wartości Min i Max z tabeli). Podejrzewam, że będzie to wymagało 2 oddzielnych wywołań za pośrednictwem ORM, podczas gdy Find_By_Sql może to zrobić w jednym wywołaniu np. find_by_sql ("Wybierz Min (t.Event_Date) z tabeli t Union Select Max (t.Event_Date) z tabeli t") – BrendanC
Zaktualizowano oryginalny wpis do użycia: join. Masz jednak rację, nie każde zapytanie można wykonać za pomocą ORM, a to nie jest celem Active Record. Został celowo zaprojektowany, aby pasował do większości potrzeb, a resztę pozostawić do dyspozycji za pomocą find_by_sql. Nie starają się zrobić wszystkiego, więc nie wahaj się użyć find_by_sql, jeśli lepiej pasuje do pracy. – ryanb