我试图找出如何在给定下面的模型定义的情况下使用AR复制以下SQL查询。演员是表演平均水平所必需的。结果集应该按条形图分组foo(来自多态关联)。任何帮助表示赞赏。
SQL:
SELECT AVG(CAST(r.foo AS decimal)) "Average", s.bar
FROM rotation r INNER JOIN cogs c ON r.cog_id = c.id
INNER JOIN sprockets s ON s.id = c.crankable_id
INNER JOIN machinists m ON r.machinist_id = m.id
WHERE c.crankable_type = 'Sprocket' AND
r.machine_id = 123 AND
m.shop_id = 1
GROUP BY s.bar
ActiveRecord模型:
class Rotation < ActiveRecord::Base
belongs_to :cog
belongs_to :machinist
belongs_to :machine
end
class Cog < ActiveRecord::Base
belongs_to :crankable, :polymorphic => true
has_many :rotation
end
class Sprocket < ActiveRecord::Base
has_many :cogs, :as => :crankable
end
class Machinist < ActiveRecord::Base
belongs_to :shop
end
更新
我已经找到了让它发挥作用的方法,但感觉就像在作弊。有没有比这更好的方法?
Sprocket.joins('INNER JOIN cogs c ON c.crankable_id = sprockets.id',
'INNER JOIN rotations r ON r.cog_id = c.id',
'INNER JOIN machinists m ON r.machinist_id = m.id')
.select('sprockets.bar', 'r.foo')
.where(:r => {:machine_id => 123}, :m => {:shop_id => 1})
.group('sprockets.bar')
.average('CAST(r.foo AS decimal)')
解
Albin的答案并没有按原样发挥作用,但确实让我找到了一个有效的解决方案。首先,我在Cog中输入了一个拼写错误,不得不改变以下关系:
has_many :rotation
复数形式:
has_many :rotations
有了这个,我可以使用以下查询
Sprocket.joins(cogs: {rotations: :machinist})
.where({ machinists: { shop_id: 1 }, rotations: { machine_id: 123}})
.group(:bar)
.average('CAST(rotations.foo AS decimal)')
唯一真正的区别是我必须将where子句分开,因为机器不属于机械师。谢谢阿尔宾!
答案 0 :(得分:0)
我认为这段代码更简单一些,并从AR
获得更多帮助Sprocket
.joins(cogs: {rotations: :machinist})
.where({ machinists: { machine_id: 123, shop_id: 1 } } )
.group(:bar)
.average('CAST(rotations.foo AS decimal)')
select子句是不必要的,您不必选择值,因为您在查询中只需要它们,AR可以帮助您决定之后需要什么。
我在我自己的一个项目中使用类似的结构对此进行了测试,但它不是完全相同的模型,因此如果不直接运行,可能会出现拼写错误。我跑了:
Activity
.joins(locations: {participants: :stuff})
.where({ stuffs: { my_field: 1 } })
.group(:title)
.average('CAST(participants.date_of_birth as decimal)')
生成此查询
SELECT AVG(CAST(participants.date_of_birth as decimal)) AS average_cast_participants_date_of_birth_as_decimal, title AS title
FROM `activities`
INNER JOIN `locations` ON `locations`.`activity_id` = `activities`.`id`
INNER JOIN `participants` ON `participants`.`location_id` = `locations`.`id`
INNER JOIN `stuffs` ON `stuffs`.`id` = `participants`.`stuff_id`
WHERE `stuffs`.`my_field` = 1
GROUP BY title
哪个AR进入如下所示的哈希:
{"dummy title"=>#<BigDecimal:7fe9fe44d3c0,'0.19652273E4',18(18)>, "stats test"=>nil}