Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用.order返回一个值,该值基于Rails 4中用户在表中的排名_Mysql_Ruby On Rails - Fatal编程技术网

Mysql 使用.order返回一个值,该值基于Rails 4中用户在表中的排名

Mysql 使用.order返回一个值,该值基于Rails 4中用户在表中的排名,mysql,ruby-on-rails,Mysql,Ruby On Rails,我试图返回一个用户在表中的排名,但我被难住了 首先,我有一个表,它记录了我游戏中的分数,名为参与。对于两名玩家,它将包含带有用户id,游戏id,最后是分数的结果,如下所示: 然后第二个结果可能是: 如果我想显示一个用户位置的排行榜,这将很容易,比如:参与。在哪里(game_id:“7”)。顺序(:asc)。我现在成功地做到了 但是,我想返回一个用户在表中排名的结果,如果按得分组织,则返回与竞争对手的排名。对于裸骨,在上面的示例中,我将让用户1和用户2都玩游戏7,并且: 用户id 1:应返回

我试图返回一个用户在表中的排名,但我被难住了

首先,我有一个表,它记录了我游戏中的分数,名为
参与
。对于两名玩家,它将包含带有
用户id
游戏id
,最后是
分数的结果,如下所示:

然后第二个结果可能是:

如果我想显示一个用户位置的排行榜,这将很容易,比如:
参与。在哪里(game_id:“7”)。顺序(:asc)
。我现在成功地做到了

但是,我想返回一个用户在表中排名的结果,如果按
得分组织,则返回与竞争对手的排名。对于裸骨,在上面的示例中,我将让用户1和用户2都玩游戏7,并且:

  • 用户id 1:应返回1作为第一名,更高的分数为2分
  • 用户id 2:第二名应返回2分,低于1分
我如何在我的控制器中重写
参与
语句,以检查用户根据分数对匹配的
游戏id
进行排名,然后根据排名分配一个整数值


对于加分,如果我可以让控制器返回该值(如用户id 1的值为1),您认为使用
update\u attributes
将其添加到
ranking
列而不是打开一个新表来存储用户排名是个坏主意吗

如果您使用的是mysql,请尝试在有序查询中使用ROW_NUMBER函数来计算排名:

Participation.select("user_id, ROW_NUMBER() AS rank").where(game_id: game_id).order(score: :asc)
生成的SQL将是:

SELECT user_id, ROW_NUMBER() AS rank FROM "participations" ORDER BY "participations"."score" ASC
我通常使用Postgres,因此无法直接测试查询,但是,它应该可以工作

如果您需要频繁访问排名列,或者需要访问单个用户/游戏对的排名,我建议您缓存排名列。您还需要设置一个后台作业,以便定期执行此操作,大约每15分钟一次。然而,上面的动态查询的好处是,它更可能是最新的,但根据该特定游戏的参与条目数量生成需要时间。

试试看

Participation.all.order("game_id asc, score desc")

我最终想出了一个策略来做这件事。同样,这里的关键是我想给一个用户分配一个“秩”,它实际上是一个整数,表示如果我们按照列
得分对所有结果排序,他们将处于哪个“行”

以下是我的流程:

    a = Participation.where(user_id: current_user.id).last.score
    b = Participation.where(user_id: current_user.id).last.id
    scores = Participation.where(game_id: params[:game_id]).where("score > ?", a).count

    if scores == 0 
        Participation.update(b, :ranking => 1)
    else 
        Participation.update(b, :ranking => scores + 1)
    end 

  end
简言之,我计算了一个特定结果的高分数。因此,如果我是用户2,并且我的分数第二高,那么这将计算1个结果。使用if/else逻辑,我想将其转换为排名,并相应地更新我的表


你可以推回这里,说排名可能需要经常更新(比如背景工作),这肯定是真的。不过,这个方法确实可以回答我最初的问题

我正在使用mysql,但在控制台中运行它时,我看到一个错误:
SQLite3::SQLException:没有这样的函数:行号:选择用户id,行号()作为从“participations”中的“participations”排序。“game\u id”=7按“participations”排序。“score”ASC
。我需要为row_number定义一个方法来实现这个功能吗?啊,sqlite不支持row_number函数。我建议在您的开发环境中使用mysql,这样您就可以可靠地针对生产中使用的同一个DB进行开发和测试。这将返回所有分数的完整列表——我想返回特定用户的排名(因此,有效地计算与该分数对应的行并将该数字作为整数返回)。我认为您现在可以在视图上执行此操作,添加
,然后在迭代查询结果时增加它。当先前的
游戏id
不等于当前时,将其重置为零。注意,您还应该将game_id的值保存到一个变量中