所以我有一个表如下:
ID_STUDENT | ID_CLASS | GRADE
-----------------------------
1 | 1 | 90
1 | 2 | 80
2 | 1 | 99
3 | 1 | 80
4 | 1 | 70
5 | 2 | 78
6 | 2 | 90
6 | 3 | 50
7 | 3 | 90
然后,我需要对它们进行分组、分类和排序,以给予:
ID_STUDENT | ID_CLASS | GRADE | RANK
------------------------------------
2 | 1 | 99 | 1
1 | 1 | 90 | 2
3 | 1 | 80 | 3
4 | 1 | 70 | 4
6 | 2 | 90 | 1
1 | 2 | 80 | 2
5 | 2 | 78 | 3
7 | 3 | 90 | 1
6 | 3 | 50 | 2
现在我知道你可以使用一个临时变量来对like here进行排序,但是我如何对一个分组的集合进行排序呢?谢谢你的见解!
8条答案
按热度按时间d7v8vwbk1#
这是一种非常简单的方式:
1.初始查询的顺序为先
id_class
,后id_student
。1.将
@student
和@class
初始化为-1
@class
用于测试是否输入了下一个集合。如果id_class
的前一个值(存储在@class
中)不等于当前值(存储在id_class
中),则@student
清零。否则递增。@class
会被指派新的值id_class
,而且它会在下一列的步骤3的测试中使用。sqxo8psd2#
Quassnoi的解决方案存在问题(标记为最佳答案)。
我有同样的问题(即模拟MySQL中的SQL窗口函数),我曾经实现Quassnoi的解决方案,使用用户定义的变量来存储前一行的值...
但是,也许在MySQL升级或其他什么之后,我的查询不再起作用了。这是因为SELECT中字段的求值顺序不能保证。@class assignment可以在@student assignment之前求值,即使它在SELECT中被放在后面。
MySQL文档中对此进行了说明,如下所示:
一般来说,您不应该在同一个陈述式中,将值指派给使用者变数并读取该值。您可能会得到预期的结果,但这并不保证。包含使用者变数之运算式的评估顺序是未定义的,而且可能会根据指定陈述式中包含的元素而变更。此外,不保证MySQL服务器的各个版本之间的顺序相同。
来源:http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
最后,我使用了一个类似的技巧,确保在阅读后指定@class:
使用left()函数只是用来设置@类变量.然后,将left()的结果(等于NULL)连接到预期的结果是透明的。
不是很优雅,但它的工作!
vc9ivgsu3#
结果:
yeotifhr4#
从上面修改,这工程,但它比我认为它需要更复杂:
u3r8eeie5#
虽然我没有足够的信誉点来评论(有点幽默),但MySQL在最近几年已经取得了很大的进步。添加了窗口函数和CTE(WITH子句),这意味着现在支持rank(和row_number等)。
我是同一个“乔恩阿姆斯特朗- Xgc”,但该帐户已失去了旧的电子邮件地址的风。
一条评论提出了一个问题,即MySQL是否支持排名窗口函数。是的,我知道
几年前,我最初的React是:
结果:
使用ROW_NUMBER窗口函数:
结果:
使用RANK窗口函数:
结果:
mccptt676#
我在一次家庭作业中遇到了类似的问题,发现MySQL(不能代表任何其他RDBMS)的RANK()方法有一个分区参数。
ma8fv8wu7#
我做了一番搜寻,找到了这篇文章才想出这样的解决办法:
你觉得哪个更好?
flseospp8#
rank()over(按class_id划分,按级别说明排序)如何?https://www.mysqltutorial.org/mysql-window-functions/mysql-rank-function/