【问题标题】:Does .where('field IN (?)', array) always return records in order?.where('field IN (?)', array) 是否总是按顺序返回记录?
【发布时间】:2014-09-24 16:00:18
【问题描述】:

是否查询:

company_ids = [2,6,15,1,3]

@people = Person.where("company_id IN (?)", company_ids)

总是返回按company_ids数组排序的@people

如果不是,最好添加.order() 之类的:

c_ids = company_ids.collect{|c_id| "company_id = #{c_id}"}

@people = Person.where("company_id IN (?)", company_ids).order( c_ids.join(',') )

【问题讨论】:

  • 如果未明确指定订购,则无法保证。
  • @SergioTulentsev 我试图避免进行不必要的排序的性能开销。感谢您的评论。
  • 如果您需要记录按顺序排列,那么您最好对它们进行排序。或者在生产中断时在半夜醒来。 :)
  • @SergioTulentsev 你知道我上面使用的排序方法是否适用于 id 数组吗?谢谢:)
  • 我非常怀疑:)

标签: ruby-on-rails rails-activerecord


【解决方案1】:
@people = Person.where("company_id IN (?)", company_ids).order(id: :desc).map(&:id)

还没有测试,你可以试试这个。

【讨论】:

  • 您不是通过给定数组对company_id 进行排序,而是通过对id 进行降序排序,然后收集这些 ID。
【解决方案2】:

不,它没有。

您可以在 SQL 中执行此操作,但查询语法将取决于您使用的数据库。对于 MySQL,这样的东西应该可以工作:

@people = Person.where("company_id IN (?)", company_ids).order("field(company_id, #{company_ids.join(',')})")

我认为在 PostgreSQL 中没有一种简单的方法可以做到这一点,但除非你有数百万行,否则你可以在 Ruby 中进行排序:

index = Person.where("company_id IN (?)", company_ids).group_by(&:company_id)
@people = company_ids.map{|id| index[id]}.flatten

---编辑---

这就是您在 PostgreSQL 中可以这样做的方式:

Person.where("company_id IN (?)", company_ids).order("CASE #{company_ids.map{|id| "WHEN company_id='#{id}' THEN #{company_ids.index(id)}"}.join(' ')} END;")

【讨论】:

  • 我需要@people 作为排序关系,这是针对 PostgreSQL 的。
  • 添加了一个 PostgreSQL 查询的小怪物,应该可以满足您的需求。
【解决方案3】:
@people = Person.where("company_id IN (?)", company_ids).order("company_id")

这将确保您始终按 company_id 排列@people。如果您还有其他期待,请发表评论。

【讨论】:

  • 这个按照company_id升序排列Person。我需要 company_id 的顺序来完全匹配company_ids 数组。
  • 哦,很酷,因为您只需添加“sort_by”,下面是代码。 @people = Person.where("company_id IN (?)", company_ids).sort_by{ |x| company_ids.index x.company_id }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 2020-09-20
  • 2018-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多