Ruby on rails 轨道外部连接、左侧连接或其他连接

Ruby on rails 轨道外部连接、左侧连接或其他连接,ruby-on-rails,join,left-join,Ruby On Rails,Join,Left Join,表格选择 user_id profile_id 表配置文件 user_id 表用户 用户有一个配置文件 配置文件属于用户 用户有很多选择 user_id profile_id 如何为用户选择不在选择表中的所有配置文件?可能是一种循环方式,需要额外的迭代。但是我想到了一个 Profile.all.reject{|pro| pro.selections.nil?} 对于纯SQL方法,它实际上总是处理数据最快的方法,我会选择: select * from profiles where i

表格选择

user_id
profile_id
表配置文件

user_id
表用户

用户有一个配置文件 配置文件属于用户 用户有很多选择

user_id
profile_id

如何为用户选择不在选择表中的所有配置文件?

可能是一种循环方式,需要额外的迭代。但是我想到了一个

Profile.all.reject{|pro| pro.selections.nil?}

对于纯SQL方法,它实际上总是处理数据最快的方法,我会选择:

select *
from   profiles
where  id not in (
         select profile_id
         from   user_profiles
         where  user_id = #{self.id})
ActiveRecord语法在连接方面做得更好,但为了简单和可读性,我倾向于将其保持为:

Profile.where("id not in (
                 select profile_id
                 from   user_profiles
                 where  user_id = ?)", self.id) 

David answer是所有答案中最正确的一个,尽管我想对一些调整有所贡献。如果您使用的是postgres,那么这篇文章值得一读:

基本上,这篇文章的要点是,有三种常用的方法:

  • 不在(已由David建议)
  • 不存在
  • LEF JOIN和检查空值
作者做了一些研究并得出结论,第二个和第三个产生了相同的解释计划,这意味着两者实际上是相同的

修改Davids的例子,它看起来是这样的

Profile.where(
  "
     NOT EXISTS (
       select 1
       from selections
       where selections.user_id = ? AND selections.profile_id = profiles.id)
  ", id) # no need to use self when calling instance methods 
ids=Selections.where(user|id:self.id).map{x|x[“user|id”]}.uniq Profile.where(['id不在(?),ids]))