مقبض سجل الاستفسارات SQL التجميعية النشطة يمكن القضبان؟
-
10-07-2019 - |
سؤال
وبدأ لتوه تعلم سجل نشط، وأنا أتساءل كيف لاسترداد البيانات من جداول متعددة حيث يشارك استعلام SQL التجميعية أفضل.
في المثال التالي (من التطبيق الطبي) أنا أبحث عن أكثر الأحداث الأخيرة من أنواع مختلفة لكل مريض (مثل آخر زيارة، وأخيرا labtest الخ). وكما ترون من الاستعلام SQL أدناه أنا أبحث عن (التاريخ) قيمة الحد الأقصى من استعلام تجميع. أنا لجأت إلى find_by_sql للقيام بذلك - ولكن أود أن نرى كيفية القيام بذلك دون استخدام find_by_sql
وIOW - كيف يمكنك الحصول على البيانات المطلوبة هنا باستخدام نهج أكتيفيريكورد النقي. وفيما يلي الجدول ورجال defs أنا اختبار مع:
والبحث بواسطة SQL لاسترداد أحدث الإدخالات لكل نوع - لاحظ "ماكس (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, 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
وفئات
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 الخاصة بك. وإليك بعض الخام، رمز لم تختبر، قد تحتاج الى بعض تافه طفيفة.
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")
ملاحظة I تعديل الأمور قليلا. أنا سميت الاسم المستعار event_date
إلى max_date
ولذلك لا يوجد أي التباس حول أي سمة كنت تقصد. سمات المستخدمة في الاستعلام :select
الخاصة بك متوفرة في النماذج التي تم إرجاعها. على سبيل المثال، في هذا يمكنك الاتصال event.max_date
. أود أيضا أن أضيف العمود id
الحدث لأنك يمكن في بعض الأحيان الحصول على بعض الأخطاء سيئة دون سمة id
(اعتمادا على كيفية استخدام نماذج عاد).
والفرق الأساسي بين :include
و:joins
هو أن ينفذ السابقة تحميل حريصة من النماذج المرتبطة بها. وبعبارة أخرى، فإنه سيتم تلقائيا جلب الكائن المريض يرتبط لكل حدث. وهذا يتطلب السيطرة على بيان select
لأنه يحتاج إلى تحديد سمات المريض في نفس الوقت. مع :joins
لا مثيل الكائنات المرضى.
نصائح أخرى
والتضمين هو مجرد اليسار ذكي الانضمام، يمكنك استخدام ذلك بالتزامن مع اختيار ومجموعة من في .find بك
في الإصدار الحالي من AR (2.3) وأعتقد أن لديك الخيار الوحيد هو استخدام find_by_sql. لماذا ا؟ لديك سمات SELECT المخصصة. أكتيفيريكورد يسمح: اختيار و: وتشمل الحجج لنداء البحث. لسوء الحظ أنها لا يمكن استخدامها جنبا إلى جنب. إذا قمت بتحديد كل من: حدد سيتم تجاهل. في المثال الخاص بك كنت في حاجة إلى اختيار للحد من الأعمدة الخاصة بك والحصول على وظيفة MAX الخاص بك.
ولقد سمعت أن هناك التصحيح / المأجور لحملهم على العمل معا، لكنني لست متأكدا من حيث هو.
والأقران