Ruby on Rails 计数和分组

发布于 2024-12-10 09:27:58 字数 1455 浏览 0 评论 0原文

需要构建一个与 SQLite 和 Postgres 一起使用的“Top 10”查询。

客户端模型 客户端 has_many :merchandises, :through => :订单,:源=> :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#show

<%= @client.top_ten_products %>

Need to build a "Top 10" query that works with SQLite and Postgres.

Client model
Client has_many :merchandises, :through => :orders, :source => :items

I want to group merchandises ordered by product_id, get the count for each and sort by most product ordered top and limit to 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}

What's missing: sort by, limit to 10 and get product.name along with quantity count

Latest development:

Items are selected but need to show 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

Console output

=> [#<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#show

<%= @client.top_ten_products %>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瞄了个咪的 2024-12-17 09:27:58

假设 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;

注意:

我将您的数量聚合更改为 < code>sum 并添加了 count 的注释列,因为我怀疑您错误地在想要求和的地方进行了计数。

Edit2:

sum() 已确认。
根据请求包含表产品中的名称。
LEFT JOIN 只是表 product 中缺少条目的预防措施,如果保证引用完整性,则可以使用普通的 JOIN 代替。

Assuming that product_id is a column of table items, the query could look like this in 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;

Note:

I changed your quantity aggregation to a sum and added a commented column for count, as I suspect you mistakenly had a count where you want a sum.

Edit2:

sum() is confirmed.
Included name from table product per request.
LEFT JOIN is just a precaution for missing entries in table product, if referential integrity is guaranteed, it can be a plain JOIN instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文