我在我的控制器中使用此代码来访问paper_weight
分类中所有用户的平均Heavy
。
if User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: 'Officepaper' } )
.pluck('avg(paper_weight)').first.nil?
@heavy_indust_officepaper == 0
else
@heavy_indust_officepaper = User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: 'Officepaper' } )
.pluck('avg(paper_weight)').first * 3
end
然后变量@heavy_indust_officepaper
显示在视图中。
问题是,当一个或多个用户在nil
中有paper_type: 'Officepaper'
条目时,上面的代码似乎无法正确计算平均值。
我知道因为industry_type: 'Heavy'
中有两个用户
其中一个有paper_type: 'Officepaper'
的一个条目,即小数30。
其他用户在nil
中有paper_type: 'Officepaper'
条目。
根据我的理解,计算应为30 + 0 / 2(users) = 15
然后15
乘以3
,这应该给45
但相反,变量@heavy_indust_officepaper
在视图中显示90
...必须是30 * 3
有没有办法在上面的代码中将nil
转换为0
???
请有人建议我吗?
以下是我今天早些时候提出的问题的链接,我从中获得了此代码的帮助Using .average with .pluck in ruby on rails app?
答案 0 :(得分:3)
这里的问题是(除其他外)是你对"hosts": ["tcp://0.0.0.0:2375"]
所做的事情的误解。它为每个用户返回一个平均 someting 的数组。所以在你的例子中它返回
pluck
这就是为什么你得到[30, nil]
(90
=> [30, nil].first * 30
)。
要获得所有用户的平均值,请使用average
。
解决方案:
在计算平均值时,您可以使用90
将COALESCE
转换为零:
NULL
需要注意的一点是,虽然User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: ['Officepaper', nil] } )
.average('COALESCE(papers.paper_weight, 0)') * 3
#=> 15
会在计算时将任何COALESCE
值转换为null
,但0
仍然会返回average
没有记录来计算nil
。
如何处理这种情况是由你决定的,但 @max 已经显示了一个非常简单的选项(假设上面的查询结果被写入average
变量):
average
答案 1 :(得分:1)
avg = User.where(industry_type: 'Heavy')
.joins(:papers)
.where(papers: { paper_type: ['Officepaper', nil] } )
.average('papers.paper_weight')
@heavy_indust_officepaper = avg.nil? ? 0 : avg * 3