0

表选择

user_id
profile_id

表型材

user_id

表用户

用户 has_one 个人资料 profile belongs_to 用户 user has_many selections

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

4

4 回答 4

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) 
于 2013-10-13T08:18:31.813 回答
0

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

Profile.all.reject{|pro| pro.selections.nil?}
于 2013-10-13T07:20:01.807 回答
0

大卫的答案是所有答案中最正确的,尽管我想贡献一点调整。如果您使用的是 postgres,那么这篇文章值得一读: http ://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/

基本上那篇文章所说的要点是,这是3种常用的方法:

  • 不在(大卫已经建议)
  • 不存在
  • LEF JOIN 和检查 NULL

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

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

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 
于 2013-10-13T09:02:37.007 回答
0
 ids =  Selection.where(user_id: self.id).map{|x|x["user_id"]}.uniq

 Profile.where(['id not in (?)', ids])
于 2013-10-13T07:39:33.777 回答