try
Request.where('(SELECT Count(*) FROM responses WHERE responses.request_id = requests.id) > 0')
Question
I'm using heroku/ rails/ pgsql 9.1.6 and banging my head against the wall around what feels like it should be a really simple query.
I want to surface recent "Requests" that a user hasn't responded to yet
Request.includes(:responses).where("(select count(responses.id)=0 WHERE responses.user=?) AND requests.created_at > ?", user_id, days_ago )
Once I push to heroku, that query generates an error:
ActiveRecord::StatementInvalid: PGError: ERROR: aggregates not allowed in WHERE clause
I found a thread on StackOverflow saying I should try "Having" instead, so I revised to
Request.includes(:responses).having("responses.user_id=? AND count(responses.id)=0", user_id).where("requests.created_at > ?", days_ago )
That generated a new error. ActiveRecord::StatementInvalid: PGError: ERROR:
column "requests.id" must appear in the GROUP BY clause or be used in an aggregate function
I then revised that query to
Request.includes(:responses).group("requests.id").group("responses.id").having("responses.user_id=? AND count(responses.id)=0", user_id).where("requests.created_at > ?", days_ago )
This runs, but returns an empty set even when I know it should return a value.
I suspect the problem at this point is with the 2 part having clause, and that in the current format it's inadvertently excluding users who haven't responded (and thus will always be an empty set):
e.g.
having("responses.user_id=? AND count(responses.id)=0", user_id)
,
as opposed to the original embedded select:
select count(responses.id)=0 WHERE responses.user=?
but I'm not sure what the right form for the having clause should be to surface users who have not responded.
Thanks in advance for any help!
Solution
try
Request.where('(SELECT Count(*) FROM responses WHERE responses.request_id = requests.id) > 0')