13

Given a situation like: Company has_many Users

To get the Companies that have 3 Users, this works efficiently:

Company.joins(:users).group("companies.id").having("COUNT(users.id)=3")

But what's the most efficient way to get the Companies that have 0 Users (none)? Because, obviously, the same approach would not work (as joins by definition excludes Companies with 0 Users):

Company.joins(:users).group("companies.id").having("COUNT(users.id)=0")

2 Answers 2

13

Do a LEFT JOIN instead of INNER JOIN.

Company.joins('LEFT OUTER JOIN users ON companies.id = users.company_id')
Sign up to request clarification or add additional context in comments.

2 Comments

I think this could be simplified by using 'includes' instead of 'joins'. Like: Company.includes(:users).group("companies.id").having("COUNT(users.id)=0")
@miguelfg : That was my initial thought as well. But no, this does not work. The error you get with this is: Unknown column 'users.id' in 'having clause'
1

As Rails continues to develop, this can now also be formulated without explicit SQL.
Also, searching companies without users is easier with an outer join and a where on null user.id:

Company.left_outer_joins(:users).where(users: {id: nil})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.