在我的Rails应用程序中,我在其中一个模型中有类似的东西
def self.calc
columns_to_sum = "sum(price_before + price_after) as price"
where('product.created_at >= ?', 1.month.ago.beginning_of_day).select(columns_to_sum)
end
对于某些行,我们将price_before
和price_after
设为nil
。这并不理想,因为我想添加两列并将其命名为price
。如何在不多次访问数据库的情况下实现这一目标?
答案 0 :(得分:4)
您可以使用NULL
确保将COALESCE
值计算为0,这将返回第一个非NULL
值:
columns_to_sum = "sum(COALESCE(price_before, 0) + COALESCE(price_after, 0)) as price"
然而,这将计算所有产品的总价。
另一方面,如果你想做的只是一个简单的方法来计算一个产品的价格,你可能不必这样做。然后,您可以向Product
模型
def.price
price_before.to_i + price_after.to_i
end
这样做的好处是能够反映价格的变化(通过price_before或price_after),而不必再次通过数据库price_before
,默认情况下将price_after
提取。
但如果你想要,例如根据将该功能放入数据库所需的价格,从数据库中选择记录。
为此,我会对您的示波器进行模块化并稍后再次加入它们:
def self.with_price
columns_to_sum = "(COALESCE(price_before, 0) + COALESCE(price_after, 0)) as price"
select(column_names, columns_to_sum)
end
这将使用额外的price
读者方法返回所有记录。
并且范围独立于之前的范围:
def self.one_month_ago
where('product.created_at >= ?', 1.month.ago.beginning_of_day)
end
然后可以这样使用:
Product.with_price.one_month_ago
这允许您在点击数据库之前继续修改范围,例如获得价格高于x
的所有产品Product.with_price.one_month_ago.where('price > 5')
答案 1 :(得分:1)
如果您要为每条记录获取price_before和price_after的总和(而不是整个查询结果的单个总和),您希望这样做:
columns_to_sum = "(coalesce(price_before, 0) + coalesce(price_after, 0)) as price"
我怀疑你之后是什么,因为你的查询中没有group
。如果你是一笔钱,那么@ulferts的答案是正确的。