简体   繁体   English

Rails User.joins.not(...)在Active Record中?

[英]Rails User.joins.not(…) in Active Record?

Im looking to query all Users without Comments in a single sql query? 我想在单个SQL查询中查询所有没有评论的用户?

Models: 楷模:

class User < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
end

So I want the opposite of this: 所以我想要与此相反:

User.joins.(:comments).group('users.id')

But not like this: (because it generates two queries) 但不是这样的:(因为它生成两个查询)

User.where.not(id: Comment.pluck(:user_id))

Maybe something like this? 也许是这样的?

User.joins.not.(:comments).group('users.id')

Thanks for any input! 感谢您的任何意见!

You can accomplish this with: 你可以用:

User.includes(:comments).where.not(comments: { id: nil })

This will result in raw SQL that looks something like: 这将导致原始SQL看起来像:

SELECT DISTINCT `users`.`*` FROM `users` LEFT OUTER JOIN `comments` ON `comments`.`user_id` = `users`.`id` WHERE `comments`.`id` IS NULL

For accomplishing this via a subquery, see the below answer. 要通过子查询完成此操作,请参阅以下答案。

Old Answer : 旧答案

You can do something like 你可以做点什么

User.where.not(id: Comment.select(:user_id))

If you wanted a single (though nested) query. 如果您想要一个(尽管是嵌套的)查询。

Otherwise, check out http://guides.rubyonrails.org/active_record_querying.html#joining-tables for using an outer join. 否则,请查看http://guides.rubyonrails.org/active_record_querying.html#joining-tables以使用外部联接。

If you are using postgresql you can do something like this 如果你使用postgresql你可以做这样的事情

User.joins("LEFT join comments c on users.id = c.comment_id").
select("users.id").
group("users.id").
having("count(users.id) = 1")

This will generate this query 这将生成此查询

select u.id from users u
LEFT join comments c 
on c.comment_id = u.id
group by u.id
having count(u.id) = 1

This query is not generating two SQL (neither nested sql), the above answer does. 这个查询不生成两个SQL(既不是嵌套的sql),上面的答案也是如此。

另一个简单的解决方案User.where("id NOT IN (?)", Comment.pluck(:user_id))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM