我有Order
模型,它有很多items
,看起来像这样
class Order < ActiveRecord::Base
has_many :items
def total
items.sum('price * quantity')
end
end
我有一个订单索引视图,像这样查询订单表
def index
@orders = Order.includes(:items)
end
然后,在视图中,我访问了订单总数,因此,您会看到大量的SUM
查询
SELECT SUM(price * quantity) FROM "items" WHERE "items"."order_id" = $1 [["order_id", 1]]
SELECT SUM(price * quantity) FROM "items" WHERE "items"."order_id" = $1 [["order_id", 2]]
SELECT SUM(price * quantity) FROM "items" WHERE "items"."order_id" = $1 [["order_id", 3]]
...
逐个加载order.total
非常慢,我想知道如何通过单个查询以急切的方式加载总和,但我仍然可以像以前一样访问order.total
。
答案 0 :(得分:0)
试试这个:
subquery = Order.joins(:items).select('orders.id, sum(items.price * items.quantity) AS total').group('orders.id')
@orders = Order.includes(:items).joins("INNER JOIN (#{subquery.to_sql}) totals ON totals.id = orders.id")
这将创建一个子查询,该子查询对订单总数进行求和,然后将该子查询加入到其他查询中。
答案 1 :(得分:0)
在此博客中,我使用find_by_sql或通过联接来解决此问题,为此我写了两个选择。
对于上面的示例,使用find_by_sql可以编写如下内容:
Order.find_by_sql("select
orders.id,
SUM(items.price * items.quantity) as total
from orders
join items
on orders.id = items.order_id
group by
order.id")
使用联接,您可以将其重写为:
Order.all.select("order.id, SUM(items.price * items.quantity) as total").joins(:items).group("order.id")
在select子句和group by子句中都将要在选择列表中包含的所有字段包括在内。希望有帮助!