【问题标题】:Rails Scope: Select Distinct Title With ValuesRails 范围:选择具有值的不同标题
【发布时间】:2012-02-09 09:31:08
【问题描述】:

我在使用范围内的 SQL 查询时遇到问题。我需要返回一组唯一的 Project.titles 及其随附的 id,以便在表单中使用。

我可以使用

获得不同的标题
scope :unique_title, select("DISTINCT title")

但我没有得到结果选项中的值

= project_form.input :id, collection: current_user.projects.unique_title

结果:

<select>
  <option value>Item 1</option>
  <option value>Item 2</option>
  <option value>Item 3</option>
</select>

所以,将 id 添加到我的范围:

scope :unique_title, select("DISTINCT title").select("id")

结果为我提供了值,但现在我的 DISTINCT 选择已失效:

<select>
  <option value="1">Item 1</option>
  <option value="2">Item 2</option>
  <option value="3">Item 3</option>
  <option value="4">Item 2</option>
  <option value="5">Item 2</option>
  <option value="6">Item 2</option>
</select>

【问题讨论】:

  • 你想要不同分组标题的 id 吗?只有第一个匹配的 id 还是具有该标题的所有 id?
  • 我希望与每个标题相关的 id 在 html 值中,例如 &lt;option value="1"&gt;Item 1&lt;/option&gt;。这样,一旦提交表单,我就可以在控制器中找到选定的选项。
  • 所以最好的方法是使用 PARTITION BY

标签: ruby-on-rails ruby-on-rails-3 rails-activerecord rails-postgresql


【解决方案1】:

我认为您将无法选择另一个字段以及 Distinct 选择保留其独特性。

我想您可能正在寻找可以在 Rails 中这样使用的GROUP BY

scope :unique_title, select("id, title").group("title")

但是,这将只选择组中具有相同标题的第一个。如果您想要所有记录但需要根据标题对其进行分组,则需要获取所有记录,然后从 Ruby 中对它们进行分组。

scope :titles, select("id, title")

然后在你使用范围的地方,你sh:

Model.titles.all.group_by(&:title).each do |distinct_title, records|
  # do something with the distinct title and records having that distinct title
end

【讨论】:

  • 我害怕那个。因此,我将这些以collection_select 的形式存在。您建议的块会嵌套在 select_tag 中吗? IE 我不知道!
【解决方案2】:

我有一段时间没做 SQL,所以这可能不会,但我会选择.select("id, title DISTINCT)

PS :如果您使用的是 Rails 3.2,您可以使用 explain 查看实际使用的查询(至少我认为可以,还没有尝试过),并且为什么它没有按您的预期工作。

【讨论】:

  • 谢谢,我确实尝试了.select("id, title DISTINCT") 查询并收到以下错误PGError: ERROR: syntax error at or near "DISTINCT" LINE 1: SELECT id, title DISTINCT FROM "workouts" WHERE "workouts".
【解决方案3】:

我采取了不同的方法来解决这个问题。

关于我的项目模型的新专栏

$ rails g migration add_template_to_project template:boolean

添加到模型中

before_create :check_if_exists

def check_if_exists
  toggle!(:template) if title.exists?
end

那么范围可以是:

scope :unique_title, select("id, title").where(template: true)

很有魅力

【讨论】:

  • 开销很大。你应该按照rubyprince的方式。它会给你你想要的,你说“独特的 Project.titles”,group by 会做到这一点。它不会为您提供具有不同 ID 的重复标题,但您不希望这样。它比上述解决方案更快、更干净。干杯。
  • 不起作用,因为您将得到“column .id\”必须出现在 GROUP BY 子句中或用于聚合函数中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 2012-03-04
  • 2021-12-30
  • 1970-01-01
相关资源
最近更新 更多