好的,所以这里是示例设置:
House
有许多CompletedJobs
属于单个Person
CompletedJobs
有一个名为total_score
的方法,它是根据模型中的数据动态生成的。输出是大于零的整数。例如:
@completed_job1.total_score #>output: 25
@completed_job2.total_score #>output: 13
我想要做的是根据最后2 CompletedJobs
的汇总得分抓住前20名Houses
,并返回Person
的{{1}}名称做了他们。
示例伪代码如下所示:
House
.last(2)
.sort_by{ SUM_OF_COMPLETED_JOBS_GROUPED_BY_PERSON }
.map{ [SUM_OF_PERSONS_JOB_SCORE, PERSON] }
.first(20)
我尝试了几种方法(从House
开始,从查询中的Person
开始),但我真的很困惑如何对得分的总和进行分组由人,然后将它们映射到一个数组。
如何在SQL(伪代码)中完成它的另一个例子:
SELECT SUM(&:total_score), person_name
FROM completed_jobs
JOINS people ON completed_job.person_id = people.id
WHERE completed_jobs.created_at > 1.week.ago ## < There are 2 per week,
## so this would grab the 2 most recent
GROUP_BY completed_job.person_id
ORDER BY &:total_score DESC
LIMIT 20
如有必要,我可以提供更多信息。
如何在Rails中组合此查询?
更新
以下查询适用于抓取CompletedJobs
每个House
# For example, let's say we only have two houses
h1 = House.first
h2 = House.last
h1_a = h1.completed_jobs.sort_by(&:total_score).map{|cj| [cj.total_score, cj.person.name]}
h2_a = h2.completed_jobs.sort_by(&:total_score).map{|cj| [cj.total_score, cj.person.name]}
如何合并h1
和h2
,然后按最高总分排序?
更新2
我能够像这样组合和求和值:
(h1_a + h2_a).group_by(&:last).map{|k,v| [k, v.map(&:first).inject(:+)]}
如何在一个查询中完成所有这些操作?我所做的一定确实有效,但看起来太黑了:)。
答案 0 :(得分:1)
我不确定你想得到什么 - 一个SQL查询?还是简短的Ruby单行?
Ruby代码:
# load all data into memory
houses = House.all.includes(completed_jobs: :person).last(2)
# process all in memory
houses.flat_map(&:completed_jobs).sort_by(&:total_score).last(20).group_by(&:person)
SQL查询(我看到唯一的方法是进行子查询):
SELECT t.name, SUM(t.total_scope)
FROM (
SELECT p.name, j.total_score
FROM houses h // may be this table is excessive but...
JOIN completed_jobs j ON j.house_id = h.id
JOIN persons p ON p.id = j.person_id
WHERE j.created_at > :week_ago_parameter
ORDER BY j.total_score
LIMIT 20
) t
GROUP BY t.name