Генерация подзапроса с помощью Arel для получения среднего значения - PullRequest
2 голосов
/ 02 марта 2011

Допустим, у меня есть несколько столов

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

Да, это прекрасно работает. Но как я могу получить запрос для среднего из этих средних?

Что такое арел, чтобы получить этот запрос?

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

Кто-нибудь знает?

Ответы [ 2 ]

3 голосов
/ 18 марта 2011

Вы можете подойти довольно близко, но 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 может использовать его как адекватный инструмент.

0 голосов
/ 08 марта 2011

Я видел ваш вопрос на Forrst - здесь есть несколько ответов, но они выглядят как обходные пути:

Вложенные запросы в Arel

Построение подзапроса с ARel в Rails3

Разве это не ключевой сбой ORM?Для чего-либо выше элементарных вызовов SQL - либо база данных будет скомпрометирована для умиротворения ORM, либо, наоборот, мы должны преобразовать SQL в AQL, BQL, CQL (вставьте собственный интерфейс текучей среды ORM здесь).

...