我有两个模型 - Question
和Answer
。
我想找到有0个答案的问题数量。
所以我尝试了这样的东西,但没有用:
Question.where("answers.count = 0").count
Question.where("answers.count", 0).count
Question.joins(:answers).where("answers.count == 0").count
以及其他一些排列。
我如何得到我想要的东西?
答案 0 :(得分:4)
虽然Edward的回答有效,但您可以并且应该使用纯sql:
Question.joins('LEFT OUTER JOIN answers.id ON answers.question_id = questions.id').group("questions.id").having("count('answers.id') = 0")
但是,如果你只想要没有答案的问题总数,我认为你不能用ActiveRecord方法做到这一点。您需要自己构建sql语句。
Question.find_by_sql(
"select count(id) as total from (
select questions.*, count(answers.id) from questions
left outer join answers on answers.question_id = questions.id
group by questions.id having count(answers.id) = 0)
as noanswers").first.total
答案 1 :(得分:3)
Question.select('questions.*, COUNT(questions.id) AS question_count').joins('LEFT OUTER JOIN questions ON questions.answer_id = answers.id').group('answers.id').select { |a| a.question_count == 0}.count
会得到你想要的。但这有点像噩梦 - 我想知道我是否遗漏了什么?
如果你想做很多复杂的查询,那么值得关注的是 - https://github.com/ernie/squeel
或者,如果您只想计算答案数,那么您可以使用counter_cache http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
以下是有关如何添加计数器缓存http://blog.obiefernandez.com/content/2011/08/adding-a-counter-cache-to-existing-records.html
的博客文章编辑 感谢@boulder指向纯sql答案
Question.joins('LEFT OUTER JOIN answers ON answers.question_id = questions.id').group('questions.id').having("count('answers.id') = 0").count
答案 2 :(得分:0)
如果您只是在命令行上执行此操作而不关心性能,那么我只需要查询Question.all.map(&:id) - Answer.all.map(&:question_id) ).uniq获取所有问题ID。基本上,您正在选择所有问题,找到问题ID,并从所有问题ID的集合中减去该集合。剩下的是没有答案的问题。
答案 3 :(得分:0)
Question.find_by_sql('select * from questions where (select count(*) from answers where question_id = question.id) = 0').count