构建用于从我的调查数据库设计中收集调查数据的查询

时间:2013-07-13 23:43:43

标签: sql ruby ruby-on-rails-3 activerecord

我有一个相对简单的模型设计,用于创建调查,为用户分配调查以及填写这些用户的调查。一切正常,但是当从这些调查中检索数据时,我处于一种状态,我不确定什么是正确的方法,尤其是rails方式。

我的模型设计如下:(为清楚起见只留下相关代码)

class Survey < ActiveRecord::Base
  has_many :survey_sections, dependent: :destroy

  has_many :survey_assignments
  has_many :participants , :through => :survey_assignments, :source => :user

  has_many :survey_responses
end

class SurveySection < ActiveRecord::Base
  belongs_to :survey
  has_many :survey_questions, dependent: :destroy
  has_many :survey_options, dependent: :destroy
end

所以调查分为很多部分,每个部分都有很多问题,每个部分都有很多选项,选项基本上是当前部分所有问题的预定义答案。这是设计决定,所以我不需要每个问题都有很多选择......

class SurveyQuestion < ActiveRecord::Base
  belongs_to :survey_section
  has_many :survey_answers
end

class SurveyAnswer < ActiveRecord::Base
  belongs_to :survey_option
  belongs_to :survey_question
  belongs_to :survey_response
end

class SurveyOption < ActiveRecord::Base
  #it has 2 fields 'weight'(int) and 'text'(string)
  belongs_to :survey_section
end

医生可以为患者分配调查,并指定他们何时可以参加调查的日期。

class SurveyAssignment < ActiveRecord::Base
  #has also a field valid_until(date)  
  belongs_to :user
  belongs_to :survey

  has_many :survey_responses
end

我也在记录调查回复。因此,每次用户填写表单时,都会创建survey_responses表中的新记录。我稍后会需要这个,因为调度实现,用户可能会分配调查,他应该[在这里输入一些数字] X [day | week | month]。

class SurveyResponse < ActiveRecord::Base
  belongs_to :survey_assignment
  belongs_to :survey
  belongs_to :user

  has_many :survey_answers
 end

现在我需要显示调查结果图表。就像你在代码中看到的那样,结果是整数(参见SurveyOption类),我需要将其添加到特定用户所采用的特定调查中。所以假设我有一个user_id和一个survey_id,现在我想要检索所有用户调查回复,但是对于每个调查回复,我需要他们的答案所具有的权重总和(SurveyOption)。

如果我进行以下查询,我会收到他所有答案的答案总和:

SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id:63).select("survey_option.weight").sum("weight")

但我想回答该用户对该调查的每个响应数组,如此

[[survey_response.created_at.to_i, the_sum_of_weights],[...],[...],....]

那么做这样的事情最好的方法是什么?是否可以在单个查询中执行此操作,如果我认为纯粹在sql状态中我认为这可以在单个查询中完成。

如果有人需要我进一步阐述,我们可以在评论中讨论。谢谢你的协助。

我想我想要生成的sql tatement是:

SELECT survey_responses.id, survey_responses.created_at, SUM (survey_options.weight) FROM "survey_responses" INNER JOIN "survey_answers" ON "survey_answers"."survey_response_id" = "survey_responses"."id" INNER JOIN "survey_options" ON "survey_options"."id" = "survey_answers"."survey_option_id" WHERE "survey_responses"."user_id" = 96 AND "survey_responses"."survey_id" = 64  GROUP BY survey_responses.id, survey_responses.created_at;

我想我已经接近解决我自己的问题:)))

1 个答案:

答案 0 :(得分:0)

经过一番研究后,我发现了一种方法。

result = SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id: 64).select("SUM (survey_options.weight) as score, survey_responses.created_at").group("survey_responses.created_at, survey_responses.id")

然后我可以在ActiveRecord :: Relation对象上使用find_each函数。

result.find_each do |r|
  puts " score: #{r.score} created_at: #{r.created_at}"
end

find_each比每个都好,因为它一次加载一批1000条记录,所以它不会占用你的记忆。想象一下,加载数百万条记录。

如果有人有更好的查询解决方案,请分享,我会接受。