مقبض سجل الاستفسارات SQL التجميعية النشطة يمكن القضبان؟

StackOverflow https://stackoverflow.com/questions/1217514

سؤال

وبدأ لتوه تعلم سجل نشط، وأنا أتساءل كيف لاسترداد البيانات من جداول متعددة حيث يشارك استعلام 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 الخاص بك.

ولقد سمعت أن هناك التصحيح / المأجور لحملهم على العمل معا، لكنني لست متأكدا من حيث هو.

والأقران

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top