9

アクティブ レコードの学習を始めたばかりで、SQL 集計クエリが関係する複数のテーブルからデータを取得する最善の方法を考えています。

次の例 (医療アプリから) では、患者ごとにさまざまな種類の最新のイベント (最後の訪問、最後のラボテストなど) を探しています。以下の sql クエリからわかるように、グループ化されたクエリから max(date) 値を探しています。これを行うためにfind_by_sqlに頼りましたが、find_by_sqlを使用せずにこれを行う方法を知りたいです。

IOW - 純粋な ActiveRecord アプローチを使用して、ここで必要なデータを取得するにはどうすればよいでしょうか。以下は、私がテストしているテーブルとクラスの定義です。

Sql で検索して、各タイプの最新のエントリを取得します - ここで「max(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、患者 ID、イベント タイプ、最新
「ハント」、3、「ラボテスト」、「2003-05-01 00:00:00」
「ハント」、3、「訪問」、「2003-03-01 00:00:00」
「セイファー」、2、「ラボテスト」、「2002-05-01 00:00:00」
'Seifer', 2, '訪問', '2002-03-01 00:00:00'

テーブルの関係は次のとおりです。
テーブル ---> 患者 --> イベント
                               --> 訪問
                               --> ラボテスト
                               --> ... その他
忍耐
      t.string :lname
      t.date :dob

イベント
      t.column :patient_id, :integer
      t.column :event_date、:datetime
      t.column :event_type, :string

訪問
      t.column :event_id, :integer
      t.column :visittype, :string

ラボテスト
      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
4

3 に答える 3

14

パランが指摘したように、:selectオプションはオプションと一緒に使用できません:include。ただし、:joinsオプションは可能です。そして、これがあなたがここで望むものです。実際、独自の SQL と同じ引数を使用し:includeたり、使用したりできます。これは大まかな、テストされていないコードです。多少の調整が必要な場合があります。

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")

少し変更したことに注意してください。event_dateエイリアスの名前を に変更したmax_dateので、参照している属性について混乱することはありません。クエリで使用される属性は:select、返されるモデルで使用できます。たとえば、これで を呼び出すことができますevent.max_date。また、返されたモデルの使用方法によってはid、属性がないと厄介なエラーが発生する場合があるため、イベント列も追加しました。id

:includeとの主な違い:joinsは、前者が関連付けられたモデルの熱心な読み込みを実行することです。つまり、イベントごとに関連する患者オブジェクトを自動的にフェッチします。selectこれには、患者属性を同時に選択する必要があるため、ステートメントの制御が必要です。:joins患者オブジェクトはインスタンス化されません。

于 2009-08-03T15:03:56.957 に答える
2

インクルードは巧妙な左結合です。.find で select および group_by と組み合わせて使用​​できます。

于 2009-08-02T09:01:05.197 に答える
0

AR (2.3) の現在のバージョンでは、唯一のオプションは find_by_sql を使用することだと思います。なんで?カスタム SELECT 属性。ActiveRecord では、find 呼び出しに :select および :include 引数を使用できます。残念ながら併用はできません。両方を指定すると、:select は無視されます。あなたの例では、選択して列を制限し、MAX 関数を取得する必要があります。

それらを連携させるためのパッチ/ハックがあると聞きましたが、それがどこにあるのかわかりません。

ピア

于 2009-08-02T00:26:08.377 に答える