我有一个表,其中有3个领域,我想排名列的基础上,用户id和游戏id。
下面是sql fiddle:http://sqlfiddle.com/#!9月883e9d/1
我的table已经有了:
user_id | game_id | game_detial_sum |
--------|---------|--------------------|
6 | 10 | 1000 |
6 | 11 | 260 |
7 | 10 | 1200 |
7 | 11 | 500 |
7 | 12 | 360 |
7 | 13 | 50 |
预期产量:
user_id | game_id | game_detial_sum | user_game_rank |
--------|---------|--------------------|------------------|
6 | 10 | 1000 | 1 |
6 | 11 | 260 | 2 |
7 | 10 | 1200 | 1 |
7 | 11 | 500 | 2 |
7 | 12 | 360 | 3 |
7 | 13 | 50 | 4 |
我目前的努力:
SET @s := 0;
SELECT user_id,game_id,game_detail,
CASE WHEN user_id = user_id THEN (@s:=@s+1)
ELSE @s = 0
END As user_game_rank
FROM game_logs
编辑:(从操作注解):排序是基于 game_detail
游戏顺序详情
4条答案
按热度按时间lmyy7pcs1#
在派生表中(在
FROM
子句),我们对数据进行排序,使所有行具有相同的user_id
值组合在一起,并根据game_detail
按降序排列。现在,我们使用这个结果集并使用条件
CASE..WHEN
用于计算行编号的表达式。它就像一种循环技术(我们在应用程序代码中使用,例如:php)。我们将前一行的值存储在用户定义的变量中,然后对照前一行检查当前行的值。最后,我们将相应地分配行号。编辑:根据mysql文档和@gordon linoff的观察:
涉及用户变量的表达式的求值顺序未定义。例如,不能保证选择@a@a:=@a+1 首先计算@a,然后执行赋值。
我们需要计算行号并分配
user_id
价值@u
同一表达式中的变量。结果
db fiddle视图
mysql文档中的一个有趣的注解,我最近发现:
mysql的早期版本允许在set以外的语句中为用户变量赋值。为了向后兼容,MySQL8.0支持此功能,但在将来的mysql版本中可能会删除此功能。
另外,感谢so的一位成员,mysql团队发现了以下博客:https://mysqlserverteam.com/row-numbering-ranking-how-to-use-less-user-variables-in-mysql-queries/
一般的观察结果是
ORDER BY
对同一查询块中的用户变量求值时,不能确保值始终正确。因此,mysql优化器可能会出现并更改我们假定的评估顺序。解决这个问题的最佳方法是升级到mysql 8+并利用
Row_Number()
功能:架构(mysql v8.0)
结果
db fiddle视图
2w3rbyxf2#
您可以使用非常简单的相关子查询:
小提琴
它比用户变量更慢,但更可靠。只需要一个连接就可以打破它们。
slsn1g293#
sqlfiddle演示
55ooxyrt4#
mysql版本8.0之前的最佳解决方案如下:
排序是在子查询中完成的。从MySQL5.7开始,这是必需的。变量赋值都在一个表达式中,所以表达式求值的不同顺序无关紧要(mysql也不保证表达式求值的顺序)。