在很多时候,都有排名这个功能,比如排行榜,并且还需要分页的功能,一般可以再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排名和分组排名的更多相关文章

  1. SQL Server 分析函数和排名函数

    分析函数基于分组,计算分组内数据的聚合值,经常会和窗口函数OVER()一起使用,使用分析函数可以很方便地计算同比和环比,获得中位数,获得分组的最大值和最小值.分析函数和聚合函数不同,不需要GROUP ...

  2. MySQL 排名、分组后组内排名、取各组的前几名 及排名后更新插入数据表中

    一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...

  3. MySQL 排名、分组后组内排名、取各组的前几名

    一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...

  4. sql server 中用于排名的三个函数 row_number() ,RANK() 和 DENSE_RANK()

    row_number()  ,RANK() 和  DENSE_RANK()  三个配合over()  使用排名 只是只是计算方式不一样,语法基本一样 语法: ROW_NUMBER() OVER (OR ...

  5. sql按天分组

    sql按天分组,这都不会 晕!!!!!!! ) ;

  6. 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 ...

  7. [MSSQL]SQL疑难杂症实战记录-巧妙利用PARTITION分组排名递增特性解决合并连续相同数据行

    问题提出 先造一些测试数据以说明题目: DECLARE @TestData TABLE(ID INT,Col1 VARCHAR(20),Col2 VARCHAR(20)) INSERT INTO @T ...

  8. ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法,先分组,然后在组内排名,分组计算,主表与附表一对多取唯一等

    ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法 今天在使用多字段去重时,由于某些字段有多种可能性,只需根据部分字段进行去重,在网上看到了row ...

  9. SQL Server排名函数与排名开窗函数

    什么是排名函数?说实话我也不甚清楚,我知道 order by 是排序用的,那么什么又是排名函数呢? 接下来看几个示例就明白了. 首先建立一个表,随便插入一些数据. ROW_NUMBER 函数:直接排序 ...

随机推荐

  1. singleTask TaskAffinity allowTaskReparenting

    关于singleTask TaskAffinity allowTaskReparenting 一.Activity的LaunchMode 1.standard 2.singleTop:FLAG_ACT ...

  2. 【USACO 3.2.3】纺车的轮子

    [描述] 一架纺车有五个纺轮,这五个不透明的轮子边缘上都有一些缺口.这些缺口必须被迅速而准确地排列好.每个轮子都有一个起始标记(在0度),这样所有的轮子都可以在统一的已知位置开始转动.轮子按照角度变大 ...

  3. archlinux的安装与简单配置(长期更新)

    安装部分较为较为简略,详细内容请查看arch的wiki 分区 cfdisk 格式化 mkfs.ext4 /dev/sdaX ... 挂载分区 mount /dev/sdaX /mnt ... 修改软件 ...

  4. 用批处理来重启IIS的应用程序池

    批处理很简单,先Stop再Start就行,代码如下(apppoolName是应用程序池的实例名):c:\windows\system32\inetsrv\AppCmd.exe stop apppool ...

  5. extjs中rowEditing动态编辑

    我们在使用Grid的rowEditing插件时希望能够根据自己的业务需求能够动态的实现那一列是用户可以编辑的,那一列用户不可编辑,下面给出一个方案能够实现rowEditing的动态编辑功能. 之前我通 ...

  6. 利用Warensoft Stock Service编写高频交易软件

    利用Warensoft Stock Service编写高频交易软件 无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法.本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft ...

  7. JS中 confirm()方法的使用?

    confirm() 方法用于显示一个带有指定消息和 OK 及取消按钮的对话框. 如果用户点击确定按钮,则 confirm() 返回 true.如果点击取消按钮,则 confirm() 返回 false ...

  8. [解决]UserLibrary中的jar包不会自动发布Tomcat的lib目录下(基于MyEclipse2014)

    1.在工程名称上单击[右键] —— 单击[Properties]选项,点击后会弹出属性窗口: 2.选择[Properties]后在左侧树中找到[MyEclipse] —— [Deployment As ...

  9. 自定义jdbc框架

    获取元数据 元数据- DataBaseMetaData DatabaseMetaData meta = con.getMetaData(); getDatabaseProductName().getD ...

  10. __file__ __name__ __doc__ argv详解

    __file__:表示输出当前py文件的路径 __name__: 表示输出当前函数名称,是main()函数(入口函数),或者是其他函数 __doc__: 模块的对象,输出模块的版权信息,如:作者 ch ...