Rails:统计唯一记录,忽略某列

Rails: Count unique records, disregarding a certain column

我有以下table

| Name   | Food  | Price |
--------------------------
| Alice  | Pizza | 5     |
| Alice  | Pizza | 10    |
| Alice  | Salad | 5     |
| Bob    | Soup  | 20    |
| Bob    | Soup  | 15    |
| Carol  | Pork  | 10    |
--------------------------

我想找到类似的东西

------------------------
| Name   | UniqueFoods |
------------------------
| Alice  | 2           | # Pizza and Salad
| Bob    | 1           | # Has only had soup, despite having it twice
| Carol  | 1           |
------------------------

我尝试过各种方法,例如

Person.select(:name, "count(*) AS uniquefoods").distinct.group(:name)

然而,这会产生

------------------------
| Name   | UniqueFoods |
------------------------
| Alice  | 3           | # incorrect
| Bob    | 2           | # incorrect
| Carol  | 1           |
------------------------

我想用只考虑 namefood 列的东西替换 .distinct,而忽略价格​​,因此它会在之前删除重复的 Name/Food 对摸索。

或者,如果有更简单的方法来生成这个 UniqueFoods 专栏,那也会有所帮助。

你把 distinct 放在了错误的地方(这对你来说没有用,因为你后面有 group)。

Person.select(:name, "count(distinct food) AS uniquefoods").group(:name)

您的原始解决方案的问题在于它的计算结果为 SELECT DISTINCT people.name, count(*) AS uniquefoods FROM people GROUP BY people.name,它计算的是每个唯一人员的食物总数。我会避免使用 select 的公认解决方案,因为它会不必要地加载您的 Person 记录,而且作为 Rails 开发人员,您永远不会编写这种语法来解决此问题。以下是更符合最佳实践的查询示例:

按名称分组并对不同的食物进行计数计算将return将名称散列到不同的食物计数:

# Here are 2 examples
Person.group(:name).distinct(:food).count(:food)
Person.group(:name).count('distinct food')
=> { "Alice" => 2, "Bob" => 1, "Carol" => 1 }

这是执行计数计算的首选解决方案,并且可以在恒定时间内很好地访问结果,因为它 return 将它们作为散列。您可以传递 group 一个或多个值以用于键,该值将是您 count 编辑的任何值。对多列进行分组时,哈希键是包含两个分组值的数组。

或者,您可以使用 pluck 到 return 一个或多个列中所需值的数组:

# Plucking 2+ columns yields a 2-dimensional array simulating rows
Person.group(:name).pluck(:name, 'count(distinct food)')
=> [["Alice", 2], ["Bob", 1], ["Carol", 1]]

# Plucking 1 column yields a 1-dimensional array simulating a column
Person.distinct(:name).pluck(:name)
=> ["Alice", "Bob", "Carol"]

Pluck 非常方便,并且比 select 具有性能优势,但最常见的是您会看到它用于 select 来自单个列的值。

Rails 查询方式一般来说真的很灵活。如果您不熟悉它,请查看 Rails AR 查询指南:https://guides.rubyonrails.org/active_record_querying.html