gpt4 book ai didi

ruby-on-rails - Rails 根据列值按计数排序

转载 作者:行者123 更新时间:2023-12-03 02:03:59 25 4
gpt4 key购买 nike

Rails 5.1.2

我有两个模型 StudentAward 这样:

class Student < ApplicationRecord
has_many :awards
end

class Award < Application Record
belongs_to :students

# Categories
scope :attendance, -> { where(category: 0) }
#...(other award categories)
scope :talent, -> { where(category: 8) }
# Ranks
# Gold
scope :rank_1, -> { where(rank: 1) }
# Silver
scope :rank_2, -> { where(rank: 2) }
# Bronze
scope :rank_3, -> { where(rank: 3) }
end

Award 包含以下列:rankcategory

现在,我想获得给定类别的尖子学生。其标准是,按“金”奖(排名 1)的数量排序,然后按“银”奖(排名 2)的数量排序,然后排序按“铜牌”(排名 3)奖项的数量。

因此,如果我要找到符合类别 0 最高标准的 Student(由 attendance 范围处理为在上面的模型中描述),我认为查询应该是这样的:

Student.joins(:awards).where(awards: { category: 0 }).group('students.id').order('COUNT(awards.rank == 1) DESC', 'COUNT(awards.rank == 2) DESC', 'COUNT(awards.rank == 3) DESC').take

但是,无论排名如何,这都会返回获得奖项最多的学生。例如,如果我删除 take,则顺序如下所示:

# |St.ID | Gold  | Slvr. | Brnz. |
----------------------------------
1 | 12 | 4 | 12 | 8 |
----------------------------------
2 | 1 | 9 | 0 | 4 |
----------------------------------
3 | 6 | 9 | 1 | 0 |
----------------------------------
4 | 18 | 5 | 2 | 2 |
----------------------------------
...

所以,我得到的顺序是 ID 12, 1, 6, 18, ...,而它应该是 ID 6, 1, 18, 12, ... ..

我意识到order('COUNT(awards.rank == 1) DESC', 'COUNT(awards.rank == 2) DESC', 'COUNT(awards.rank == 3) DESC') 部分只是按奖励总数(而不是排名 列中具有特定值的奖励计数)进行排序。

我可以通过为每个奖项类别添加计数器缓存来轻松解决这个问题,但这不是一个优雅且灵活的解决方案。

作为奖励,在该查询返回成功结果后,我将再次搜索数据库以查找所有具有相同分数的学生(因为可能存在平局)。我不知道有一种方法可以在一个查询中完成所有这些操作(也许在获取每个排名的值后通过子查询的方式)。

最佳答案

我认为你的问题可能是双重等于?

编辑:这是一个更合适的方法(假设MySQL):

 Student.joins(:awards).where(awards: { category: 0 }).group('students.id').order('COUNT(if(awards.rank = 1)) DESC', 'COUNT(if(awards.rank = 2)) DESC', 'COUNT(if(awards.rank = 3)) DESC').take

首先在没有它的情况下尝试您的代码,如果这不起作用,您可能想尝试以下操作:

SELECT students.id, gold, silver, bronze) FROM students 
JOIN ON
(SELECT students.id as id COUNT(awards) as bronze
FROM students JOIN awards ON students.id = awards.student_id
WHERE awards.rank = 1
GROUP BY students.id) q1 q1.id = students.id
JOIN ON
(SELECT students.id as id COUNT(awards) as silver
FROM students JOIN awards ON students.id = awards.student_id
WHERE awards.rank = 2
GROUP BY students.id) q2 q2.id = students.id
JOIN ON
(SELECT students.id as id COUNT(awards) as gold
FROM students JOIN awards ON students.id = awards.student_id
WHERE awards.rank = 3
GROUP BY students.id) q3 q3.id = students.id
ORDER BY gold, silver, bronze

关于ruby-on-rails - Rails 根据列值按计数排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45318204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com