【问题标题】:Rails: Count unique records, disregarding a certain columnRails:计算唯一记录,忽略特定列
【发布时间】:2021-06-24 01:26:01
【问题描述】:

我有下表

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

我想将 .distinct 替换为仅考虑 namefood 列且不考虑价格的内容,因此它会在摸索之前删除重复的名称/食物对。

或者,如果有更简单的方法来生成此UniqueFoods 列,那也会有所帮助。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    您将distinct 放在了错误的位置(这在您的情况下没有用,因为您后面有group)。

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

    【讨论】:

      【解决方案2】:

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

      按名称分组并对不同食物执行计数计算会将名称哈希返回到不同食物计数:

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

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

      或者,您可以使用pluck 从一列或多列中返回所需值的数组:

      # 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 具有性能优势,但最常见的是您会看到它用于从单个列中选择值。

      Rails 查询方法通常非常灵活。如果您不熟悉它,请查看关于 AR 查询的 Rails 指南:https://guides.rubyonrails.org/active_record_querying.html

      【讨论】:

        猜你喜欢
        • 2016-05-31
        • 2011-09-22
        • 2021-02-22
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        • 2018-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多