我有三个表格,其中包含模具(模具)的详细信息,以及通过流派表格链接在一起的模式:
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都有一个Scroll模式,所以我应该能够编写以下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或建议一种更好的rails方式来进行这种查询吗?
答案 0 :(得分:1)
我已经测试了你上面的模型和数据,我得到了你期望的结果(即三个模具名称" A4"," A6"和& #34; A8&#34)。所以我怀疑你的数据正在发生。
除此之外,我建议使用Rails query methods来获取所需的数据,而不是诉诸SQL。例如,这个:
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几乎相同,并产生相同的结果(同样,正确的结果有三个结果)。
请注意,SQL的INNER JOIN genres g
部分在此处没有明确提及。只要您在through
和Mould
上定义了Pattern
个关联,就可以使用此功能:
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
由于您告诉Rails Mould
和Pattern
通过genres
表关联,因此它知道如何构建正确的SQL查询以将它们连接在一起。
希望有所帮助。