简体   繁体   中英

Trouble converting my MySQL query to rails active record format

I have the following MySQL query which returns 1 column called points populated with integer values

SELECT SUM(points) FROM (SELECT FLOOR((sum(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points FROM answersheets WHERE user_id = 133 GROUP BY exercise_id, user_id) as points

I've got it to the following point as a ruby on rails scope which is the sub query without the final sum to get a total:

scope :base_points, ->(user_id) { select('FLOOR((SUM(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points').where('user_id = ?', user_id).group(:exercise_id, :user_id) }

But that just returns

 2.1.0 :073 > p = Answersheet.base_points(133)
 Answersheet Load (0.4ms)  SELECT FLOOR((SUM(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points FROM `answersheets` WHERE (user_id = 133) GROUP BY exercise_id, user_id
 => #<ActiveRecord::Relation [#<Answersheet id: nil>, #<Answersheet id: nil>, #<Answersheet id: nil>]>

What could be causing the difference between the rails console and the mysql one? My guess is bad formatting on my part

Method based on chosen answer below

def points
    query = Answersheet.select('FLOOR((SUM(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points').where('user_id = ?', self.id).group(:exercise_id, :user_id)
    return query.sum(&:points)
end

Note: This is so I can do @user.points so I've moved the code to the user model

Try changing your scope to:

scope :base_points, ->(user_id) { select('FLOOR((SUM(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points').where('user_id = ?', user_id).group(:exercise_id, :user_id).first[:points] }

I think it would be better to write this as a method though:

class Answersheet < ActiveRecord::Base

  def self.base_points(user_id)
    scoped.select('FLOOR((SUM(case when correct=1 then correct else 0 end)/COUNT(*))*100) as points').
      where('user_id = ?', user_id).
      group(:exercise_id, :user_id).
      first[:points]
  end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM