问题
What I'm trying to do is determine what rank a sales person came in for a month as far as earning commission goes in the least amount of steps possible. I think it might be possible to do with a combination of ActiveRecord + some enumerable methods, but essentially I have a model that looks like the following:
class Employee < ActiveRecord::Base
validates :commission, presence: true
end
commission is just an integer. So in order to get all employees ordered from highest to lowest for commission earned, we can do something as trivial as:
Employee.order('commission desc')
My question is, assume that the employee I'm looking for has an id of 50. What's an easy way of knowing what "rank" they are in as far as commission earned. If they are at the top of the list, they have earned a rank of #1. If they are last in the descending sort, their rank is ultimately the size of Employee.all.count
Employees who share the same commission amount should be ranked the same. Multiple employees sharing a rank is correct.
回答1:
MySQL doesn't have any native ranking functions, so you'll need to resort to the GROUP_CONCAT method to get this to work efficiently:
Employee.
select('employees.*, FIND_IN_SET(commission, ranks) AS rank').
joins(', (SELECT GROUP_CONCAT(DISTINCT commission, ORDER BY commission DESC) AS ranks FROM employees) ranks').
order('commission desc')
You can also use the self-join approach commonly used, but performance will likely degrade significantly as the table grows.
回答2:
Couldn't you just count how many employees had higher commissions:
Employee.where('commission > ?', Employee.find(50).commission).count + 1
credit to:
How to calculate a record's ranking compared to others based on a single column in Rails?
The downside with that literal approach is two queries, but the id lookup should be fast, if it's not already cached or otherwise available, e.g., if you had already instantiated an object for that employee from which you could just get the commission without another query.
来源:https://stackoverflow.com/questions/22277613/activerecord-rails-4-determine-index-of-record-in-query