一个问题有很多答案。
很容易找到所有已回答的问题,并按最新答案排序:
def self.answered
joins(:answers).order('answers.created_at desc')
end
在控制器中,我会做@answered = Question.answered
但如果问题被多次回答,则会返回重复记录。
另一方面,很容易找到已经回答的不同问题,但前提是我没有尝试通过他们的答案 created_at日期来订购它们:def self.answered
joins(:answers).select("DISTINCT questions.title")
end
(我们假设这里的问题标题是唯一的,所以这会产生所有独特的记录。)
问题:
此查询无法按答案的“created_at”日期排序,因为我在SQL select语句中仅选择了问题的标题... < / p>
def self.answered
joins(:answers).select("DISTINCT questions.title").order('answers.created_at desc')
end
导致此错误(我正在使用Postgres):
PGError: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
我想,这意味着它是否希望在选择DISTINCT语句中看到“answers.created_at”。
如果我想通过questions.created_at订购,以下情况会有效,但这不是我想要的:
def self.answered
joins(:answers).select("DISTINCT(questions.title), questions.created_at").order('questions.created_at desc')
end
这是我的基本SQL知识的用武之地。如何选择不同的问题(只有答案的问题)并按照最新答案的created_at日期按降序排列?
我想使用Rails 3 Active Record查询来编写它,但是直接的SQL很好。我希望有人可以提供帮助。
答案 0 :(得分:1)
为什么不使用write as:
def self.answered
joins(:answers).order("answers.created_at DESC").group("questions.id")
end
这将完全符合您的要求:)
答案 1 :(得分:1)
以下是我能够与PG合作的方式:
def self.answered
scoped.select("questions.title").group("questions.title").joins(:answers).having('MAX(answers.created_at) IS NOT NULL').order('MAX(answers.created_at) DESC')
end
或者,如果您要为问题选择整个ActiveRecord行,则可以按questions
中的每一列选择/分组:
def self.answered
cols = self.column_names.collect{ |c| "#{table_name}.#{c}" }.join(',')
scoped.select(cols).group(cols).joins(:answers).having('MAX(answers.created_at) IS NOT NULL').order('MAX(answers.created_at) DESC')
end
答案 2 :(得分:0)
我可以为它编写SQL解决方案。它将如下所示:
select q.id "Qn-ID", q.question, q.created_at "Qn-CreatedAt", a.id "Ans-ID", a.answer, a.created_at "Ans-CreatedAt" from questions q, answers a where a.question_id = q.id and a.id in (select max(id) answer_id from answers group by question_id) order by "Ans-CreatedAt" desc
希望它有所帮助!
答案 3 :(得分:0)
这可能最终会更有效和可扩展,并且应该避免psql抱怨聚合函数的问题:
select questions.*, count(answers.id) as answer_count from questions join answers on answers.question_id=questions.id group by answers.question_id having answer_count > 0 order by answers.created_at desc
P.S。通过可扩展我的意思是,您可以将其拆分为Arel结构,然后打破范围,例如with_answers并回答在幕后进行脏工作,同时保持其余部分清洁并允许您稍后添加更多范围。 :)
更新:只发布Arel方式:
scope :answered, select('questions.*, count(answers.id) as answer_count').joins('join answers on answers.question_id=questions.id').group('answers.question_id').having('answer_count > 0').order('answers.created_at desc')