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 (‘79‘, ‘张三‘, ‘数学‘);

INSERT INTO `test` VALUES (‘69‘, ‘张三‘, ‘语文‘);

INSERT INTO `test` VALUES (‘57‘, ‘张三‘, ‘英语‘);

INSERT INTO `test` VALUES (‘81‘, ‘李四‘, ‘数学‘);

INSERT INTO `test` VALUES (‘45‘, ‘李四‘, ‘语文‘);

INSERT INTO `test` VALUES (‘84‘, ‘李四‘, ‘英语‘);

INSERT INTO `test` VALUES (‘15‘, ‘王五‘, ‘数学‘);

INSERT INTO `test` VALUES (‘47‘, ‘王五‘, ‘语文‘);

如果要查询数学科目的排名,可以用以下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;  

时间: 2024-10-11 16:25:40

Sql排名和分组排名的相关文章

SQL按字段分组取最大(小)值记录(重复记录)

SQL Server 按某一字段分组 取 最大 (小)值所在行的数据 -- 按某一字段分组 取 最大 (小)值所在行的数据 -- (爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-10-23于浙江杭州) /* 数据如下: name val memo a    2   a2(a的第二个值) a    1   a1--a的第一个值 a    3   a3:a的第三个值 b    1   b1--b的第一个值 b    3   b3:b的第三个值 b    2   b2b2b2b2 b   

最常用的SQL排序、分组与统计的使用方法

以一种有意义的方式组织数据可能是一项挑战.有时你需要的可能是一个简单的排序,但是通常你需要做更多,你需要分组来进行分析和统计.幸运的是,SQL提供了大量语句和操作来进行排序,分组和摘要.下面的一些技巧将会帮助你识别什么时候排序,什么时候分组,什么时候以及如何统计.对要每条语句和操作的详细信息请查看Books Online. 1. 使用排序使数据有序 通常,你的所有数据真正需要的仅仅是按某种顺序排列.SQL的ORDER BY语句可以以字母或数字顺序组织数据.因此,相似的值按组排序在一起.然而,这个

(转)最常用的SQL排序、分组与统计的使用方法 Order by/Group by/having等的使用

以一种有意义的方式组织数据可能是一项挑战.有时你需要的可能是一个简单的排序,但是通常你需要做更多,你需要分组来进行分析和统计.幸运的 是,SQL提供了大量语句和操作来进行排序,分组和摘要.下面的一些技巧将会帮助你识别什么时候排序,什么时候分组,什么时候以及如何统计.对要每条语句 和操作的详细信息请查看Books Online. 1. 使用排序使数据有序 通常,你的所有数据真正需要的仅仅是按某种顺序排列.SQL的ORDER BY语句可以以字母或数字顺序组织数据.因此,相似的值按组排序在一起.然而,

sql按天分组

sql按天分组,这都不会 晕!!!!!!! select to_char(createtime,'yyyymmdd'),count(1) from os_user_config_0705 group by to_char(createtime,'yyyymmdd') order by 1;

app下载排名与收入排名-----App排行榜

http://www.appannie.com/indexes/all-stores/rank/games/?month=2014-05-01 闲来无事 ,看看app排名. 来自于五月份全球app排名 包括安android平台和IOS平台. 从表中看除中国.日本外 ,绝大部分为欧美公司. 而收入排行榜上中国仅腾讯一家上榜.岛国地方不大占五家公司.排名第一是芬兰Supercell公司. 收入排名第一的app也是芬兰Supercell公司. app下载排行,中国公司占四位 .收入排行中日本公司占五位

seo快排技术/seo快速排名/搜索引擎快速排名/百度快速排名/搜索引擎快排/百度排名/百度优化/百度快排

seo快排技术/seo快速排名/搜索快速排名/百度快速排名/搜索引擎快排/搜索引擎快速排名技术的强大工具: 泛目录技术是目前最快速有效的办法,增加站点的收录方面,这里推荐莲花泛目录 莲花泛目录,完善的技术支持,代码亲自编写,独立研发.业界领先. 莲花泛目录程序强大之处: 1.内容分类详细2.自动推送URL链接3.内置超强原创内容功能系统,页面深受百度搜索引擎喜爱.4.蜘蛛触发繁殖:蜘蛛触发程序任何页面,程序自动生成独立页面并引导繁殖.5.操作容易简单:全部采用web界面配置,简单鼠标点击操作即可

在Sql Server中实现分组排名

比如我们有这样一个表,表名是table1,这个表里面存储了某班同学中考所有的科目成绩, 假设如下: 这时候,老师要求查出每个科目同学的成绩排名,排名函数之前我们用的最多的就是row_number() over()了.但在默认情况下,这个排名函数是不分科目的,也就是不分组的,它会把所有的成绩按照高或低进行排名 select * ,ROW_NUMBER()OVER(ORDER BY [分数] desc) as id from [table1] ORDER BY [课程] 执行得到的查询结果如下: 这

数据库排名sql,group by 分组查询按照时间最大值

先给出类似的简单表 DROP TABLE IF EXISTS `TouTiaoAnchor`; CREATE TABLE `TouTiaoAnchor` ( `HourId` int(10) unsigned NOT NULL, `BetinTime` varchar(40) NOT NULL, `AnchorUid` int(11) unsigned NOT NULL, `ticket` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '闪耀值',

ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法,先分组,然后在组内排名,分组计算等

ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法 今天在使用多字段去重时,由于某些字段有多种可能性,只需根据部分字段进行去重,在网上看到了rownumber() over(partition by col1 order by col2)去重的方法,很不错,在此记录分享下: row_number() OVER ( PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算