Sql排名和分组排名
在很多时候,都有排名这个功能,比如排行榜,并且还需要分页的功能,一般可以再select的时候按照某一字段 oorder by XX desc,这样limit 查找就可以得到排名信息,但是有时候是需要多表连接,或者是有一个随机查看,在页面上并不是按照排名升降序。这个时候就需要用SQL来实现排名。
先准备测试数据:
Table:
CREATE TABLE `test` (
`Score` int(255) NOT NULL,
`Name` varchar(255) NOT NULL,
`Type` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES ('', '张三', '数学');
INSERT INTO `test` VALUES ('', '张三', '语文');
INSERT INTO `test` VALUES ('', '张三', '英语');
INSERT INTO `test` VALUES ('', '李四', '数学');
INSERT INTO `test` VALUES ('', '李四', '语文');
INSERT INTO `test` VALUES ('', '李四', '英语');
INSERT INTO `test` VALUES ('', '王五', '数学');
INSERT INTO `test` VALUES ('', '王五', '语文');

如果要查询数学科目的排名,可以用以下sql语句:
select a.*,@a := @a+1 as rank from test a,(select @a:=0) b where type=' 数学 ' order by a.score desc;
结果如下:

也就是使用a变量,按照order by的顺序递增。这个很好理解,但是如果有分组排序的需求呢?
例如在Test表中,要用一条sql查出数学、语文、英语三个科目各自的排名呢?
首先可以想到方法还是类似查询单科排名,先将所有记录按照科目、得分排序,Order by Type,Score。然后自定义变量递增,但是关键就在于需要判断科目的记录有多少条,也即自定义变量归零重新递增的临界点。
简单排名使用一个变量a,那么在分组排序中可以考虑使用两个变量,a、b
先执行如下sql
select a.* from test a order by type,score;

现在加上排名,先使用一个变量看得到什么效果:
select a.*,(@a := @a + 1) as rank from test a,(select @a := 0) b order by type,score;

现在排名并没有按照科目的不同重新计算,我们只要解决排名何时归0,就可以得到分组排序的结果了。
再加一个中间变量nowType试试?让这个中间变量nowType等于Type(科目),只要下一条记录与这个中间变量nowType相等,rank就加1,不相等的话,rank就归零,来看下这条SQL:
select a.*,@lastType := @nowType,@ nowType:= a.type,if(@lastType = @nowType,@rank := @rank + 1,@rank := 0) as rank from test a,(select @a := 0,@ nowType:= 0,@rank := 0) b order by type,score;
现在看来是不是比较简单了,lastType用于记录上一条记录的Type,nowType是当前记录的Type,只要nowType=lastType,就说明是同一科目,rank加+,反之,rank归零。

但是我们看到同样是将rank初始化为0,为什么上面是从1开始,而这次是从0开始呢?再分析下sql,在第一条记录的时候,lastType=0.而nowType=数学,肯定不相等,所以输出0,rank从0开始,只要将rank初始化为1就好了。
select a.*,@lastType := @temp,@temp := a.type,if(@lastType = @temp,@rank := @rank + 1,@rank := 1) as rank from test a,(select @a := 0,@temp := 0,@rank := 0) b order by type,score;

Sql排名和分组排名的更多相关文章
- SQL Server 分析函数和排名函数
分析函数基于分组,计算分组内数据的聚合值,经常会和窗口函数OVER()一起使用,使用分析函数可以很方便地计算同比和环比,获得中位数,获得分组的最大值和最小值.分析函数和聚合函数不同,不需要GROUP ...
- MySQL 排名、分组后组内排名、取各组的前几名 及排名后更新插入数据表中
一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...
- MySQL 排名、分组后组内排名、取各组的前几名
一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...
- sql server 中用于排名的三个函数 row_number() ,RANK() 和 DENSE_RANK()
row_number() ,RANK() 和 DENSE_RANK() 三个配合over() 使用排名 只是只是计算方式不一样,语法基本一样 语法: ROW_NUMBER() OVER (OR ...
- sql按天分组
sql按天分组,这都不会 晕!!!!!!! ) ;
- SQL Server温故系列(5):SQL 查询之分组查询 GROUP BY
1.GROUP BY 与聚合函数 2.GROUP BY 与 HAVING 3.GROUP BY 扩展分组 3.1.GROUP BY ROLLUP 3.2.GROUP BY CUBE 3.3.GROUP ...
- [MSSQL]SQL疑难杂症实战记录-巧妙利用PARTITION分组排名递增特性解决合并连续相同数据行
问题提出 先造一些测试数据以说明题目: DECLARE @TestData TABLE(ID INT,Col1 VARCHAR(20),Col2 VARCHAR(20)) INSERT INTO @T ...
- ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法,先分组,然后在组内排名,分组计算,主表与附表一对多取唯一等
ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法 今天在使用多字段去重时,由于某些字段有多种可能性,只需根据部分字段进行去重,在网上看到了row ...
- SQL Server排名函数与排名开窗函数
什么是排名函数?说实话我也不甚清楚,我知道 order by 是排序用的,那么什么又是排名函数呢? 接下来看几个示例就明白了. 首先建立一个表,随便插入一些数据. ROW_NUMBER 函数:直接排序 ...
随机推荐
- UITouch触摸事件
UITouch触摸事件 主要为三个方法 1.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{2.3. UITouch * ...
- Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view...
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tabl ...
- 解决 Ubuntu15.04 登陆界面无限循环 的问题
本人新手,在学习linux 安装NVIDIA 驱动的时候出现了一个奇怪的问题:登陆界面输入正确的账户密码,短暂闪烁后又返回了登陆界面.经查阅多种资料,已解决此问题 以下内容来自:http://blog ...
- Linux命令学习计划【sed】
引言: Sed命令是linux里用于文本行处理的命令. 为了便于说明,我在/usr/dict下创建了字典words并以此作为演示模板 先用nl 打印下words内容: *打印篇: Q1:如何打印某一行 ...
- JQUERY1.9学习笔记 之基本过滤器(十一) 奇数选择器
奇数选择器jQuery( ":odd" ) 例:匹配表格的奇数行. <!DOCTYPE html><html lang="zh-cn"> ...
- table表格cellspacing与cellpadding属性
cellspacing属性 用来指定表格各单元格之间的空隙. cellpadding属性 用来指定单元格内容与单元格边界之间的空白距离的大小. 此属性的参数值也是数字,表示单元格内容与上下边界之间空白 ...
- Can't connect to local MySQL server through socket
今天上午在测试代码的时候发现在执行写mysql的时候总是超时,然后失败,使用mysql命令 show processlist; 发现有两条update的sql语句已经执行了很长时间,以为是这两个程序把 ...
- TCP回射服务器程序:str_echo函数
str_echo函数执行处理每个客户的服务: 从客户读入数据,并把它们回射给客户 读入缓冲区并回射其中内容: read函数从套接字读入数据,writen函数把其中内容回射给客户 如果客户关闭连接,那么 ...
- getsockname和getpeername函数
这2个函数或者返回与某个套接字关联的本地协议地址(getsockname),或者返回与某个套接字关联的外地协议地址(getpeername) int getsockname(int sockfd, s ...
- C#复习,输入学生信息排列成绩
C#复习:在控制台程序中使用结构体.集合,完成下列要求项目要求:一.连续输入5个学生的信息,每个学生都有以下4个内容:1.序号 - 根据输入的顺序自动生成,不需要手动填写,如输入第一个学生的序号是1, ...