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 函数:直接排序 ...
随机推荐
- Android中使用PullToRefreshListView遇到的问题
1.布局文件中要是设置visible属性为Gone的时候,注意了,这样会有一个bug,在代码中setVisible的时候设置为VISIBLE是不起作用的..这个应该是自身的一个小bug(本人目前没有找 ...
- Android onConfigurationChanged(Configuration cfg) 无法触发问题
1.android:configChanges="orientation|keyboardHidden"的使用 当在activity加上android:configChange ...
- android handler机制简单介绍
我们需要了解4个类: handler:处理者,用于发送和接收信息 massage:消息.里面可以存储消息的许多信息 looper:循环泵,用于循环取出消息队列中的消息 MessageQueue(一般不 ...
- 使用top工具,找出消耗CPU 较多的进程
1.使用top工具,找出消耗CPU 较多的进程 [oracle@cuug ~]$ top top - 10:48:27 up 23:15, 4 users, load average: 1.09, ...
- react服务端渲染(同构)
学习react也有一段时间了,使用react后首页渲染的速度与seo一直不理想.打算研究一下react神奇服务端渲染. react服务端渲染只能使用nodejs做服务端语言实现前后端同构,在后台对re ...
- javascript之attribute 和 property
首先看看这两个单词的英文释义(来自有道词典).先是property: property ['prɔpəti] n. 性质,性能:财产:所有权 英英释义: any area set aside for ...
- 简洁的MysqlHelper
把MySqlXXX的类更改为SqlXXX就可以成为sqlHelper. 另外C#也提供了MysqlHelper和sqlHelper,用起来也挺方便的. public class MySqlHelper ...
- OpenGL画图旋转
#include<gl/glut.h>#include<gl/GL.h>#include<gl/GLU.h>#include<math.h>#inclu ...
- js学习笔记之:键盘应用
为了方便用户操作,可以为用户设置(或者屏蔽)功能键,代替使用频率比较高的操作.本次,将学习一下基本的功能键使用方法.键盘和焦点使用.屏蔽按键等知识点,以及一些相关示例: 1 设置按键功能: 功能键主要 ...
- Tinkphp定时发布文章的教程
第一步:在文章表中加一个字段,用来保存定时发布的时间 假定我把这个字段设为 push_time 默认为 0 第二步:写一个方法来检查文章列表,把文章列表到时间的文章改为发布状态 //定时发布文章 pu ...