mysql计算排名 转
from :http://www.cnblogs.com/aeiou/p/5719396.html
http://www.cnblogs.com/zengguowang/p/5541431.html
mysql计算排名,获取行号rowno
学生成绩表数据
SELECT * FROM table_score ORDER BY score DESC;

获取某个学生成绩排名并计算该学生和上一名学生成绩差,是并列排名
SELECT *,
(SELECT count(DISTINCT score) FROM table_score AS b WHERE a.score<b.score)+1 AS rank, #获取排名,并列
(SELECT b.score FROM table_score AS b WHERE b.score>a.score ORDER BY b.score LIMIT 1)-a.score AS subtract #获取和上一名学生成绩的差
FROM table_score AS a WHERE a.s_id = 13; #获取学生周三的成绩排名和与上一名的成绩差

获取所有学生成绩排名-并列排名
SELECT *,
(SELECT count(DISTINCT score) FROM table_score AS b WHERE a.score<b.score)+1 AS rank #获取排名-并列
FROM table_score AS a ORDER BY rank; #获取学生成绩排名

获取所有学生成绩排名,不是并列排名。计算行号进行排名
SELECT a.*,
(@rowNum:=@rowNum+1) AS rank #计算行号FROM table_score AS a,
(SELECT (@rowNum :=0) ) b
ORDER BY a.score DESC;

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sql语句查询排名
思路:有点类似循环里面的自增一样,设置一个变量并赋予初始值,循环一次自增加1,从而实现排序;
mysql里则是需要先将数据查询出来并先行按照需要排序的字段做好降序desc,或则升序asc,设置好排序的变量(初始值为0):
a>.将已经排序好的数据从第一条依次取出来,取一条就自增加一,实现从1到最后的一个排名
b>.当出现相同的数据时,排名保持不变,此时则需要再设置一个变量,用来记录上一条数据的值,跟当前数据的值进行对比,如果相同,则排名不变,不相同则排名自增加1
c.当出现相同的数据时,排名保持不变,但是保持不变的排名依旧会占用一个位置,也就是类似于(1,2,2,2,5)这种排名就是属于中间的三个排名是一样的,但是第五个排名按照上面一种情况是(1,2,2,2,3),现在则是排名相同也会占据排名的位置
准备数据(用户id,分数):
CREATE TABLE `sql_rank` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`score` tinyint(3) unsigned NOT NULL,
`add_time` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
插入数据:
INSERT INTO sql_rank (user_id, score, add_time)
VALUES
(100, 50, '2016-05-01'),
(101, 30, '2016-05-01'),
(102, 20, '2016-05-01'),
(103, 60, '2016-05-01'),
(104, 80, '2016-05-01'),
(105, 50, '2016-05-01'),
(106, 70, '2016-05-01'),
(107, 85, '2016-05-01'),
(108, 60, '2016-05-01')
当前数据库数据:

一、sql1{不管数据相同与否,排名依次排序(1,2,3,4,5,6,7.....)}

SELECT
obj.user_id,obj.score,@rownum := @rownum + 1 AS rownum
FROM
(
SELECT
user_id,
score
FROM
`sql_rank`
ORDER BY
score DESC
) AS obj,
(SELECT @rownum := 0) r

执行的结果如下图:

可以看到,现在按照分数从1到9都排好序了,但是有些分数相同的用户排名却不一样,这就是接下来要说的第二种sql
二、sql2{只要数据有相同的排名就一样,排名依次排序(1,2,2,3,3,4,5.....)}

SELECT
obj.user_id,
obj.score,
CASE
WHEN @rowtotal = obj.score THEN
@rownum
WHEN @rowtotal := obj.score THEN
@rownum :=@rownum + 1
WHEN @rowtotal = 0 THEN
@rownum :=@rownum + 1
END AS rownum
FROM
(
SELECT
user_id,
score
FROM
`sql_rank`
ORDER BY
score DESC
) AS obj,
(SELECT @rownum := 0 ,@rowtotal := NULL) r

这时候就新增加了一个变量,用于记录上一条数据的分数了,只要当前数据分数跟上一条数据的分数比较,相同分数的排名就不变,不相同分数的排名就加一,并且更新变量的分数值为该条数据的分数,依次比较
如下图结果:

跟第一条sql的结果相对比你会发现,分数相同的排名也相同,并且最后一名的名次由第9名变成了第7名;
如果你需要分数相同的排名也相同,但是后面的排名不能受到分数相同排名相同而不占位的影响,也就是哪怕你排名相同,你也占了这个位置(比如:1,2,2,4,5,5,7....这种形式的,虽然排名有相同,但是你占位了,后续的排名根据占位来排)
三、sql2{只要数据有相同的排名就一样,但是相同排名也占位,排名依次排序(1,2,2,4,5,5,7.....)}
此时需呀再增加一个变量,来记录排序的号码(自增)

SELECT
obj_new.user_id,
obj_new.score,
obj_new.rownum
FROM
(
SELECT
obj.user_id,
obj.score,
@rownum := @rownum + 1 AS num_tmp,
@incrnum := CASE
WHEN @rowtotal = obj.score THEN
@incrnum
WHEN @rowtotal := obj.score THEN
@rownum
END AS rownum
FROM
(
SELECT
user_id,
score
FROM
`sql_rank`
ORDER BY
score DESC
) AS obj,
(
SELECT
@rownum := 0 ,@rowtotal := NULL ,@incrnum := 0
) r
) AS obj_new

上面sql执行的结果如下:

结果集中分数相同的,排名相同,同时它也占据了那个位置,中间的一个数据过程本人截图了,请往下看(跟上图做对比你就明白了):

mysql计算排名 转的更多相关文章
- mysql计算排名
mysql计算排名,获取行号rowno 学生成绩表数据 SELECT * FROM table_score ORDER BY score DESC; 获取某个学生成绩排名并计算该学生和上一名学生成绩差 ...
- mysql成绩排名
关于mysql成绩排名,网上大部分只是order by简单排序,忽略了成绩相同并列名次的问题. 定义了一个表score结构为:
- mysql计算时间差函数
MySql计算两个日期的时间差函数TIMESTAMPDIFF用法,只要用一句SQL语句就可以办到了. MySql计算两个日期的时间差函数TIMESTAMPDIFF用法: 语法: TIMESTAMPDI ...
- MySQL计算时间差
MySQL计算两个日期的时间差函数:TIMESTAMPDIFF 语法: TIMESTAMPDIFF(interval, datetime_expr1, datetime_expr2) interval ...
- mysql计算连续天数,mysql连续登录天数,连续天数统计
mysql计算连续天数,mysql连续登录天数,连续天数统计 >>>>>>>>>>>>>>>>>& ...
- MySql计算两个日期的时间差函数
MySql计算两个日期时间的差函数: 第一种:TIMESTAMPDIFF函数,需要传入三个参数,第一个是比较的类型,可以比较FRAC_SECOND.SECOND. MINUTE. HOUR. DAY. ...
- MySQL实现排名并查询指定用户排名功能,并列排名功能
MySQL实现排名并查询指定用户排名功能,并列排名功能 表结构: CREATE TABLE test.testsort ( id int(11) NOT NULL AUTO_INCREMENT, ui ...
- MySQL计算日期的函数DATE_SUB(d,INTERVAL expr type)
MySQL计算日期的函数DATE_SUB(d,INTERVAL expr type) DATE_SUB(d,INTERVAL expr type)函数返回起始日期d减去一个时间段后的日期. expr是 ...
- MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数
MySql计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数 计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,这里主要分享的是通过MySql内置的函数 TimeStampDiff() ...
随机推荐
- 最基本的CentOS 网络配置
一般CentOS 网络配置是根据自己的需求来设定的.但是,对于一些不经常用CentOS的用户来说,不知道基本的CentOS 网络配置.如果你没有特别的要考虑的设置,那么就可以考虑下我推荐的这种Cent ...
- Codeforces791A Bear and Big Brother
A. Bear and Big Brother time limit per test 1 second memory limit per test 256 megabytes input stand ...
- 14.combobox自动搜索
前台页面: 后台查询:
- 初始Yarn
YARN 产生背景 MapReduce1.x存在的问题:单点故障&节点压力大.不易扩展 资源利用率&运维成本 催生了YARN的诞生 YARN:不同计算框架可以共享同一个HDFS集群上的 ...
- ASP.NET MVC Owin 基本理解
一.OWIN OWIN(Open Web Interface for .Net),定义了一个服务器(IIS)和Web应用程序(MVC,Webform)通信的标准接口,并且通过抽象层使得这两个在微软平台 ...
- Web应用安全之点击劫持(CLICKJACKING)与X-FRAME-OPTIONS HEADER
点击劫持(clickjacking)与X-Frame-Options Header 文/玄魂 目录 前言... 1.1 点击劫持(clickjacking attacks)... 1.2 Frame ...
- [转]高端又易学的vbs表白程序了解一下
第一个. 打开txt文件,复制以下代码粘贴进去(可以修改中文部分,其它代码不要动!).保存并关闭txt文件. msgbox("做我女朋友好吗?") msgbox("房产证 ...
- python3 os.path.realpath(__file__) 和 os.path.cwd() 方法的区别
python3 os.path.realpath(__file__) 和 os.path.cwd() 方法的区别 os.path.realpath 获取当前执行脚本的绝对路径. os.path.rea ...
- JavaScript对象与JSON字符串的相互转换
JSON(JavaScript Object Notation) 是JavaScript编程语言的一个子集.正因JSON是JavaScript的一个子集,所以它可清晰的运用于此语言中. eval函数 ...
- Liferay开发实战(1):入门
网址: https://www.liferay.com/zh/ 文档: https://dev.liferay.com/develop 入门文章网上很多,中文的较少,存在版本太旧的问题,也缺少一步一步 ...