select 在 Rails 中使用 ActiveRecord 和 PostgreSQL 无法区分每个组的行

Not able to select distinct row from each group using ActiveRecord with PostgreSQL in Rails

我的 ActiveRecord 查询有一个小问题。
我有一个产品模型,它看起来像:

#<Product id: nil, name: nil, price: nil, order_id: nil, created_at: nil, updated_at: nil, restaurant_id: nil>

现在我想 select 区分所有名称,并取回所有产品的属性。

我试过了:

@products = Product.where(restaurant_id: !nil).group("products.name").order("name")

但是我得到了这个错误:

PG::GroupingError: ERROR:  column "products.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT  "products".* FROM "products"  WHERE "products"."rest...
                ^
: SELECT  "products".* FROM "products"  WHERE "products"."restaurant_id" = 1 GROUP BY products.name  

好的,然后我将 product_id 添加到我的查询中:

@products = Product.where(restaurant_id: !nil).group("products.name, products.id").order("name")

但此查询 returns 产品具有重名。 所以我也尝试了这个:

@products = Product.where(restaurant_id: !nil).select("DISTINCT(NAME)").order("name")

但在 return 中我只得到了只有 ID 和名称的产品记录(很明显),所以如果这个查询 return 设置正确,我添加了我稍后需要的属性:

@products = Product.where(restaurant_id: !nil).select("DISTINCT(NAME), restaurant_id, price").order("name")

而且return也是重名。

您有任何解决方案或想法,如何解决 PostgreSQL 的此查询?
我习惯这样写查询(在 MySQL 上),它是正确的:

@products = Product.where(restaurant_id: !nil).select("DISTINCT(NAME), restaurant_id, price").order("name")

为什么 PostreSQL 不接受该查询?

您应该将查询写成:-

Product.where
       .not(restaurant_id: nil)
       .select("DISTINCT ON(name) name, restaurant_id, price, updated_at")
       .order("updated_at, name")

根据官方文档SELECT DISTINCT ON ( expression [, ...] )

keeps only the first row of each set of rows where the given expressions evaluate to equal. The DISTINCT ON expressions are interpreted using the same rules as for ORDER BY (see above). Note that the "first row" of each set is unpredictable unless ORDER BY is used to ensure that the desired row appears first. For example:

SELECT DISTINCT ON (location) location, time, report
FROM weather_reports
ORDER BY location, time DESC;

retrieves the most recent weather report for each location. But if we had not used ORDER BY to force descending order of time values for each location, we'd have gotten a report from an unpredictable time for each location.