3

私はRubyonRailsから始めたばかりで、もう少し複雑なクエリについて質問があります。これまで、Railsガイドを見ながら簡単なクエリを実行してきましたが、非常にうまく機能しました。

現在、データベースからいくつかのIDを取得しようとしています。これらのIDを使用して、実際のオブジェクトを取得し、それらを使用して何かを実行します。それらを取得することは、単純なObject.findメソッドよりも少し複雑です。

これが私のクエリがどのように見えるかです:

select * from quotas q, requests r
where q.id=r.quota_id
and q.status=3
and r.text is not null
and q.id in
(
select A.id from (
select max(id) as id, name 
from quotas
group by name) A
)
order by q.created_at desc
limit 1000;

これにより、SQLマネージャーからこのクエリを実行するときに1000個のIDが得られます。そして、最初にIDのリストを取得してから、IDでオブジェクトを見つけることを考えていました。

このクエリを使用してこれらのオブジェクトを直接取得する方法はありますか?IDルックアップを回避しますか?私はあなたがこのようなクエリを実行できることをグーグルで検索しました:

ActiveRecord::Base.connection.execute(query);
4

2 に答える 2

3

と仮定するとQuota has_many :requests

Quota.includes(:requests).
  where(status:3).
  where('requests.text is not null').
  where("quotas.id in (#{subquery_string_here})").
  order('quotas.created_at desc').limit(1000)

私は決して専門家ではありませんが、ほとんどの基本的な SQL 機能は ActiveRecord に組み込まれています。醜い文字列サブクエリを排除する方法については、 メソッド#groupとメソッドを参照することもできます。#pluck

リレーションシップ オブジェクトを呼び出す#to_sqlと、それと同等の SQL コマンドが表示され、デバッグに役立つ場合があります。

于 2013-02-22T08:33:16.897 に答える
0

これには find_by_sql を使用します。これが正確であると断言するつもりはありませんが、思い出すと、SQL ステートメントを find_by_sql に入れることができ、結果の列は、呼び出したクラスのオブジェクトの配列の属性として返されます。

  status = 3
  Quota.find_by_sql('
    select * 
    from quotas q, requests r
    where q.id=r.quota_id
    and q.status= ?
    and r.text is not null
    and q.id in
    (
      select A.id from (
      select max(id) as id, name 
      from quotas
      group by name) A
    )
    order by q.created_at desc
    limit 1000;', status)

生の SQL を書くのに慣れている人として Rails に来たのであれば、ActiveRecord のメソッドをたくさん並べるよりも、おそらくこの構文を使用した方がよいでしょう。

ところで、SQL クエリ内で文字列補間 (つまり #{variable} 構文) を使用しないでください。使用 '?' 代わりに構文を使用して (私の例を参照)、SQL インジェクションの可能性を回避します。

于 2013-02-22T09:53:04.043 に答える