Add new `having` methods
I think using HAVING isn't super common, but when you need it, it's pretty nice.
I had a thought about how this might look, but since I rarely use this function, I'm not sure if my idea here covers a wide enough case or not.. I think to start we could have 2 methods. The first being having which might work similar to where(raw_sql : String). This would let you just write what you need as an escape hatch.
The second (and subsequent) methods would work similar to a column method, but also piggy back off the aggregate functions.
# or maybe just having_count ?
def having_select_count(exact_match : Int)
having_select_count.eq(exact_match)
end
def having_select_count
end
Then it could look like this:
# give me all users that have exactly 4 draft posts
UserQuery.new.where_posts(PostQuery.new.published(false).having_select_count(4)).group(&.id)
# give me all users that have at least 2 published posts
UserQuery.new.where_posts(PostQuery.new.published(true).having_count.gte(2)).group(&.id)
This would give us
SELECT users.*
FROM users
INNER JOIN posts on posts.user_id = users.id
WHERE posts.published = 'f'
GROUP BY users.id
HAVING COUNT(posts.*) = 4
SELECT users.*
FROM users
INNER JOIN posts on posts.user_id = users.id
WHERE posts.published = 't'
GROUP BY users.id
HAVING COUNT(posts.*) >= 2
Or of course you could do UserQuery.new.where_posts(...).group(&.id).having("COUNT(posts.*) > ?", 4)
The others could be like having_sum having_min, having_max, etc...