我有一个复杂的查询,我无法理解(使用sql或ActiveRecord),以下是我的模型:
class Contact
has_many :profile_answers
end
class ProfileAnswer
belongs_to :contact
belongs_to :profile_question
end
class ProfileQuestion
has_many :profile_answers
end我正在试图找到两个联系人的ProfileAnswers号,对于特定的ProfileQuestion具有相同的value。换言之:
获得两个联系人对特定profile_question的响应值相同的配置文件答案的总数。
我不想做多个查询和筛选,因为我知道这是可能的,只有Sql,我只是不知道如何做
我曾经考虑过profile_answers在profile_question_id上的自连接,然后通过value进行过滤,但是我仍然无法理解这一点。任何帮助都是非常感谢的。
发布于 2011-05-26 21:44:49
我认为这样可以:
SELECT COUNT(DISTINCT profile_question_id)
FROM
( SELECT profile_question_id
FROM ProfileAnswer an
JOIN ProfileQuestion qu
ON qu.id = an.profile_question_id
WHERE contact_id IN ( id1, id2 )
GROUP BY profile_question_id
, value
HAVING COUNT(*) = 2
) AS grp而且JOIN似乎没有被使用。所以,如果ProfileAnswer.profile_question_id是NOT NULL,这就足够了:
SELECT COUNT(*)
FROM
( SELECT profile_question_id
FROM ProfileAnswer
WHERE contact_id IN ( id1, id2 )
GROUP BY profile_question_id
, value
HAVING COUNT(*) = 2
) AS grp为两个特定的联系人( ids为id1和id2)编辑。
添加WHERE并将COUNT (DINSTINCT )更改为COUNT(*)。
也许这个带有JOIN的版本可以更容易地适应ActiveRecord。
使用JOIN的
SELECT COUNT(*)
FROM ProfileAnswer a
JOIN ProfileAnswer b
ON a.profile_question_id = b.profile_question_id
AND a.value = b.value
WHERE a.contact_id = id1
AND b.contact_id = id2 发布于 2011-05-27 14:45:23
我是这样做的,再次感谢@ypercube:
class ProfileAnswer < ActiveRecord::Base
def self.for_contacts(*contacts)
where :contact_id => contacts.collect(&:id)
end
def self.common_for_contacts(*contacts)
select(:profile_question_id).for_contacts(*contacts).group(:profile_question_id, :value).having("count(*) = #{contacts.length}")
end
def self.common_count_for_contacts(*contacts)
find_by_sql("select count(*) as answer_count from (#{common_for_contacts(*contacts).to_sql})").first.answer_count
end
end
# Usage
ProfileAnswer.common_count_for_contacts(contact1, contact2[, contact3...])最后仍然必须使用一个find_by_sql作为嵌套选择.不知道有什么办法吗??
同样令人烦恼的是,find_by_sql返回一个数组,因此我不得不使用.first,后者给出了在其中包含answer_count属性的对象。
https://stackoverflow.com/questions/6145345
复制相似问题