【问题标题】:Generating a subquery with Arel to get an average of averages使用 Arel 生成子查询以获得平均值
【发布时间】:2011-03-02 08:19:16
【问题描述】:

假设我有几张桌子

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;"

有人知道吗?

【问题讨论】:

    标签: sql ruby-on-rails aggregate arel


    【解决方案1】:

    您可以非常接近,但 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 可以作为适当的工具来处理它。

    【讨论】:

    【解决方案2】:

    我在 Forrst 上看到了您的问题 - 这里有几个答案,但它们看起来像是解决方法:

    Nested queries in Arel

    Building a subquery with ARel in Rails3

    这不是ORM的关键失败吗?对于基本 SQL 调用之上的任何内容 - 要么数据库受到损害以安抚 ORM,要么相反我们必须将 SQL 转换为 AQL、BQL、CQL(在此处插入专有的 ORM 流体接口)。

    【讨论】:

    • 原则上不是ORM的失败。这是某些 ORM 实现的失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    相关资源
    最近更新 更多