1

金型 (金型) の詳細とそのパターンを含む 3 つのテーブルが、ジャンル テーブルを介してリンクされています。

Mould table
id : integer
name : string


Pattern table
id : integer
name : string

genres table
id : integer
mould_id :integer
pattern_id : integer

次のようにテーブルにデータがあります

Mould table
ID          Name
1           A1
2           A2
3           A3
53          A4
54          A5
197         A6
198         A7
1204        A8
1205        A9

Pattern Table

ID         Name
1          Running
2          Scroll

Genres Table

ID     mould_id  pattern_id
1       1           1
2       2           1
3       3           1
4       53          1
5       53          2
6       54          1
7       197         2
8       198         1
9       1204        2
10      1205        1

私の計算では、金型 53、197、および 1204 はすべてスクロールのパターンを持っているため、次の SQL を記述してそれを与えることができるはずです。

SELECT m.id   FROM moulds m INNER JOIN genres g
ON m.id = g.mould_id INNER JOIN patterns p
ON g.pattern_id = p.id  
WHERE p.id = 2     
GROUP BY m.id    
HAVING COUNT(*) >= 1

しかし、それは197しか返さないので、何かが間違っています(または私のデータに問題があります)

次に、それをRailsに変換しますfind_by_sqlでラップします。これは同じ結果をもたらします(これは理にかなっています)

誰かが SQL を手伝ったり、この種のクエリを実行するためのより良い方法を提案したりできますか?

4

1 に答える 1

1

上記のモデルとデータをテストしたところ、期待どおりの結果が得られました (つまり、「A4」、「A6」、「A8」という名前の 3 つの金型)。だから私はあなたのデータで何かが起こっていると思います.

それはさておき、SQL に頼るのではなく、 Railsクエリ メソッドを使用して目的のデータを取得することをお勧めします。たとえば、次のようになります。

Mould.select('moulds.id')\
     .joins(:patterns)\
     .where('patterns.id' => 2)\
     .group('moulds.id')\
     .having('COUNT(*) >= ?', 1)

次の SQL が生成されます。

SELECT moulds.id FROM "moulds"
INNER JOIN "genres" ON "genres"."mould_id" = "moulds"."id"
INNER JOIN "patterns" ON "patterns"."id" = "genres"."pattern_id"
WHERE "patterns"."id" = 2
GROUP BY moulds.id
HAVING COUNT(*) >= 1

これはあなたが持っている SQL とほとんど同じで、同じ結果を生成します (ここでも、3 つの結果を持つ正しいものです)。

INNER JOIN genres gSQL の一部は、明示的に言及せずにここに出てくることに注意してください。これは、と でthrough関連付けが定義されている限り機能します。MouldPattern

class Mould < ActiveRecord::Base
  has_many :genres
  has_many :patterns, :through => :genres
  #...
end

class Pattern < ActiveRecord::Base
  has_many :genres
  has_many :moulds, :through => :genres
  #...
end

Mouldテーブルを介してとPatternが関連付けられていることを Rails に伝えるため、Rails はgenresそれらを結合するための正しい SQL クエリを作成する方法を知っています。

それが役立つことを願っています。

于 2013-01-23T12:44:20.093 に答える