Рубин на рельсах кол и группы - PullRequest
0 голосов
/ 17 октября 2011

Необходимо создать запрос "Top 10", который работает с SQLite и Postgres.

Модель клиента Клиент has_many :merchandises, :through => :orders, :source => :items

Я хочу сгруппировать товары, упорядоченные по product_id, получить количество для каждого и отсортировать по большинству товаров, упорядоченных сверху и ограничить до 10.

Client.last.merchandises.group(:product_id).count(:quantity)
SELECT COUNT("items"."quantity") AS count_quantity, product_id AS product_id FROM "items" INNER JOIN "orders" ON "items"."order_id" = "orders"."id" WHERE "orders"."client_id" = 2 GROUP BY product_id
=> {1=>91, 2=>1, 12=>1, 32=>1, 33=>1, 34=>1, 37=>1, 75=>1, 84=>1, 85=>1}

Чего не хватает: сортировка, ограничение до 10 и получение product.name вместе с количеством

Последняя разработка:

Элементы выбраны, но необходимо указать product.name

class Client < ActiveRecord::Base 
def top_ten_products
  Item.find_by_sql(
    "SELECT i.product_id, sum(i.quantity) AS sum_quantity
    FROM   orders o
    JOIN   items i ON i.order_id = o.id 
    WHERE  o.client_id = 2 
    GROUP  BY 1
    ORDER  BY 2 DESC
    LIMIT  10;"
   )
 end

Консольный вывод

=> [#<Item product_id: 1>, #<Item product_id: 37>, #<Item product_id: 75>, #<Item product_id: 12>, #<Item product_id: 32>, #<Item product_id: 33>, #<Item product_id: 2>, #<Item product_id: 34>, #<Item product_id: 84>, #<Item product_id: 85>] 

Клиент # показать

<%= @client.top_ten_products %>

1 Ответ

1 голос
/ 17 октября 2011

Если предположить, что product_id является столбцом таблицы items, запрос может выглядеть следующим образом в PostgreSQL :

SELECT i.product_id
      ,p.name
      ,sum(i.quantity) AS sum_quantity
FROM   orders o
JOIN   items i ON i.order_id = o.id 
LEFT   JOIN product p USING (product_id)
WHERE  o.client_id = 2 
GROUP  BY 1,2
ORDER  BY 3 DESC, 2 -- with same quantity, order by name
LIMIT  10;

Примечание:

Я изменил вашу количественную агрегацию на sum и добавил столбец с комментариями для count, так как я подозреваю, что вы ошибочно подсчитали, где вы хотите получить сумму.

Edit2:

sum() подтверждено. Включено наименование из таблицы товаров по запросу.
LEFT JOIN - это всего лишь мера предосторожности для пропущенных записей в таблице product, если ссылочная целостность гарантирована, вместо нее может быть просто JOIN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...