【问题标题】:select vs distinct vs uniq?select vs distinct vs uniq?
【发布时间】:2016-08-11 06:34:25
【问题描述】:

我对 Ruby 的 ActiveRecord uniq 方法感到困惑。我正在使用它来尝试取回一组完整的对象,而不仅仅是一个特定的字段。

在我的 Padrino 应用程序脚本中,将报纸名称和分数保存为 Score 对象,ActiveRecord 关系上的 uniq 方法按属性不起作用,并且无论是否使用 SQL 语法,两者都不同。谁能解释发生了什么?

class Score < ActiveRecord::Base

    def self.from_today
        self.where('created_at > ?', Date.today)
    end
end


scores = Score.from_today
scores.class      
=> Score::ActiveRecord_Relation 

scores.first
=> #<Score id: 123, score: -2.55, source: "Mail", created_at: "2016-08-11 04:29:24", updated_at: "2016-08-11 04:29:24">

scores.map(&:source) 
=> ["Mail", "Guardian", "Telegraph", "Independent", "Express", "Mail"]

scores.uniq(:source).count 
=> 6

scores.distinct(:source).count
=> 6

scores.select('distinct (SOURCE)').count
=> 5    #AHA, it works!

scores.select(:source).distinct
=> #<ActiveRecord::Relation [#<Score id: nil, source: "Telegraph">, #<Score id: nil, source: "Mail">, #<Score id: nil, source: "Independent">, #<Score id: nil, source: "Express">, #<Score id: nil, source: "Guardian">]>

        #oops, no it doesn't

【问题讨论】:

  • 那么你想要的结果集是什么?
  • 我正在使用它来尝试取回一组完整的对象,而不仅仅是一个特定的字段。

标签: sql ruby-on-rails ruby activerecord padrino


【解决方案1】:

在 Rails 5 中 distinct 没有参数。在 Rails 4.2 中,参数只有 truefalse。当true 时,返回不同的记录,当false 时返回无不同的记录。 uniq 在这种情况下只是 distinct 的别名

所以对于 Rails 4

scores.select(:source).distinct.count 是你想要的。这将distinct 限制为source

【讨论】:

  • 但它不会返回完整的对象,对吗?
  • scores.select(:source).distinct 不返回完整对象。仅具有已填充源列的对象。因为你不能说你想要其他属性的值。例如带有source 邮件的对象应该有created_at?记录 123 的值还是其他?
  • 那么如何取回所有具有唯一 :source 属性的 Score 对象?
  • 对于您的示例,您想要除源为Mail 的对象之外的所有分数对象?或者您想要所有得分对象,包括源为Mail 的第一个或最后一个对象?
猜你喜欢
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 2013-10-18
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
相关资源
最近更新 更多