假设我有一些表格
orders = Arel::Table.new :orders
stores = Arel::Table.new :stores
managers = Arel::Table.new :managers
经理有很多商店,商店有很多订单。
有一天,我想查询经理工作的订单的平均总数。哦,我想把商店分组。所以要明确一点,我想得到一位经理的平均订单总额,对于他们工作的每家商店。
让我们假设我们已经找到了我们的经理:
manager = Manager.find(some_id)
totals = orders.where(orders[:store_id].in(manager.store_ids)).group(orders.store_id).project(orders[:total].average)
puts totals.to_sql
"SELECT AVG(`orders`.`total`) AS avg_id FROM `orders` WHERE `orders`.`store_id` IN (1, 2, 3) GROUP BY `orders`.`store_id`"
是的,这很棒。但是,如何查询这些平均值的平均值呢?
获取此查询的Arel是什么?
"SELECT AVG(avg_id) FROM (SELECT AVG(`orders`.`total`) AS avg_id FROM `orders` WHERE `orders`.`store_id` IN (1, 2, 3) GROUP BY `orders`.`store_id`) as avg_id_alias;"
有人知道吗?
答案 0 :(得分:2)
你可以非常接近,但ActiveRecord不支持直接执行Arel结构,你必须先将它们转换为SQL。
这是一个类似于你正在做的事情的例子:
o = Orders.arel_table
o_avg = Orders.select(:avg[:store_id].as('avg_id')).
where(:store_id => [1,2,3]).group(:store_id)
Orders.find_by_sql("select avg(avg_id) from (#{o_avg.to_sql})")
对这种妥协感到高兴。 ActiveRecord非常不适合一次收集多个模型的聚合数据 ,如果您明智地将SQL打包在一起,那么Arel可以将服务器作为一个适当的工具。
答案 1 :(得分:0)
我在Forrst上看到了你的问题 - 这里有几个答案,但它们看起来像是解决方法:
Building a subquery with ARel in Rails3
这不是ORM的关键失败吗?对于基本SQL调用之外的任何事情 - 数据库被破坏以安抚ORM,或者反过来我们必须将SQL转换为AQL,BQL,CQL(在此处插入专有的ORM流体接口)。