Rails外连接,左连接或其他一些连接

时间:2013-10-13 07:05:06

标签: ruby-on-rails join left-join

表格选择

user_id
profile_id

表格简介

user_id

表用户

用户has_one个人资料 个人资料belongs_to用户 用户has_many选择

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

4 个答案:

答案 0 :(得分:1)

对于一个纯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) 

答案 1 :(得分:0)

可以通过额外的迭代进行循环。但是我想到了一个。

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

答案 2 :(得分:0)

 ids =  Selection.where(user_id: self.id).map{|x|x["user_id"]}.uniq

 Profile.where(['id not in (?)', ids])

答案 3 :(得分:0)

David回答是所有答案中最正确的答案,尽管我想做一些调整。如果你使用postgres比这篇文章值得一读: http://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/

基本上该文章所说的要点是,这是通常的3种方法:

  • NOT IN(David已经建议)
  • NOT EXISTS
  • LEF JOIN并检查NULLs

作者做了一些研究并得出结论第二和第三个产生相同的解释计划,这意味着两者几乎相同。

修改戴维斯的例子看起来像这样

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