Generating a subquery with Arel to get an average of averages

风格不统一 提交于 2020-01-04 17:49:29

问题


Lets say I have a few of tables

orders = Arel::Table.new :orders
stores = Arel::Table.new :stores
managers = Arel::Table.new :managers

And a manager has many stores and a store has many orders.

One day I want to query for the average total across orders where a manager works. Oh, I want to group that by the store. So to be clear, I want to get the average order total for a manager, for each of the stores they work at.

And let's assume we've looked up our manager:

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

Yup, that works great. But how can I get a query for the average of those averages?

What's the Arel to get this query?

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

Anybody know?


回答1:


You can get pretty close, but ActiveRecord doesn't support the execution of Arel structures directly, you have to convert them to SQL first.

Here's an example of something similar to what you're doing:

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})")

Be happy with this compromise. ActiveRecord is poorly suited to gather aggregate data about more than one model at a time, and if you wisely are leery of patching SQL together, then Arel can server as an adequate tool for it.




回答2:


I saw your question up on Forrst - there are a couple of answers here, but they look like workarounds:

Nested queries in Arel

Building a subquery with ARel in Rails3

Isn't this a key failing of ORM? For anything above rudimentary SQL calls - either the database gets compromised to appease the ORM, or conversely we have to convert the SQL into AQL,BQL,CQL (insert proprietary ORM fluid interface here).



来源:https://stackoverflow.com/questions/5165002/generating-a-subquery-with-arel-to-get-an-average-of-averages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!