from :http://www.cnblogs.com/aeiou/p/5719396.html html
http://www.cnblogs.com/zengguowang/p/5541431.htmlmysql
mysql计算排名,获取行号rownosql
学生成绩表数据数据库
SELECT * FROM table_score ORDER BY score DESC;
获取某个学生成绩排名并计算该学生和上一名学生成绩差,是并列排名spa
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; #获取学生周三的成绩排名和与上一名的成绩差
获取全部学生成绩排名-并列排名3d
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; #获取学生成绩排名
获取全部学生成绩排名,不是并列排名。计算行号进行排名code
SELECT a.*, (@rowNum:=@rowNum+1) AS rank #计算行号FROM table_score AS a, (SELECT (@rowNum :=0) ) b ORDER BY a.score DESC;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------htm
sql语句查询排名blog
思路:有点相似循环里面的自增同样,设置一个变量并赋予初始值,循环一次自增长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')
当前数据库数据:
1、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
2、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....这种形式的,虽然排名有相同,可是你占位了,后续的排名根据占位来排)
3、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执行的结果以下:
结果集中分数相同的,排名相同,同时它也占据了那个位置,中间的一个数据过程本人截图了,请往下看(跟上图作对比你就明白了):