1

Ruby onRails2.3.5を使用してSQLiteデータベースから一連のモデルを受け取っています。現在、本当に必要なものだけを選択するためにサブクエリを使用しています。

find(:all, 
  :conditions => "foo.id in (
                    SELECT bar.foo_id FROM bar
                    JOIN baz
                      ON baz.bar_id = bar.id
                    WHERE baz.bla in (1, 2, 3)
                  )"
)

サブクエリはすべての行に対して同じ結果を評価し、SQLiteは最適化できることに気付くほど賢くないので、これはばかげていることを私は知っています。だから私はそれをクエリから外したいと思います。2番目を使用してRailsから簡単に呼び出すことができることは知っていfind()ますが、サブクエリの戻り値が比較的大きくなる可能性があることを考えると、データベース内のすべてを実行したいので、データベースとRails。

では、モデルを実行してfind()、実際のサブクエリの戻り値を検索し、その結果を他の行の比較に使用する必要があることをどのように伝えることができますか?find()これをSQLiteへの1回の呼び出しで渡すことはできますか?

4

3 に答える 3

0

次のようなことができるでしょうか。

    subs = connection.select_rows("SELECT bar.foo_id FROM bar
                                   JOIN baz
                                   ON baz.bar_id = bar.id
                                   WHERE baz.bla in (1, 2, 3)")
    find(:all, :conditions => "foo.id in (#{subs.join(',')})")

これは私がRails3で書き直そうとしていることです。

于 2012-05-23T17:33:34.813 に答える
0

一般に、モデルで関係を定義するようにしてください。そうすれば、ActiveRecordのヘルパーを簡単に使用できます

class Foo < ActiveRecord::Base
  self.table_name = "foo"

  has_many :bars
end

class Bar < ActiveRecord::Base
  self.table_name = "bar"

  belongs_to :foo
  has_many :bazs
end

class Baz < ActiveRecord::Base
  self.table_name = "baz"

  belongs_to :bar
end

これらのモデルを配置すると、次のようなクエリを記述できます。

Foo.find(:all, :include => {:bar => :baz}, :conditions => ["#{Baz.table_name}.id IN (?)", [1,2,3]])
于 2012-05-23T17:54:32.327 に答える
0

次のモデルが与えられます:

class Foo < ActiveRecord::Base
  has_many :bars
  has_many :bazs, :through => :bars

  attr_accessible :title
end


class Bar < ActiveRecord::Base
  belongs_to :foo
  has_many :bazs

  attr_accessible :title
end


class Baz < ActiveRecord::Base
  belongs_to :bar

  attr_accessible :title
end

あなたはできる:

Foo.all(
  :joins => { :bars => :bazs },
  :conditions => { :bars => { :bazs => { :id => [1000] } } }
)

1000興味のあるバズのIDはどこにありますか。

これにより、次のSQLが生成されます。

SELECT "foos".* FROM "foos" INNER JOIN "bars" ON "bars"."foo_id" = "foos"."id" INNER JOIN "bazs" ON "bazs"."bar_id" = "bars"."id" WHERE "bazs"."id" IN (1000)

これを行った場合も同じです。

Foo.all(
  :joins => { :bars => :bazs },
  :conditions => { :bazs => { :id => [1000] } }
)

またはさらに良いことに、through関連付けを使用します。

Foo.all(
  :joins => [:bazs],
  :conditions => { :bazs => { :id => [1000] } }
)

その結果、その基準に一致するすべてのFooレコードが作成され、SQLは同じになります。

それがあなたの質問に答えることを願っています。

于 2012-05-24T13:48:14.383 に答える