SQL实现group by 分组后组内排序

在一个月黑风高的夜晚,自己无聊学习的SQL的时候,练习,突发奇想的想实现一个功能查询,一张成绩表有如下字段,班级ID,英语成绩,数据成绩,语文成绩如下图

实现 查询出 每个班级英语成绩最高的前两名的记录。

看起来不难的业务,做起来才知道还挺麻烦的,说白了其实就是实现分组后的组内排序,一般不思考的话我们会写出这样的语句:

select top 2 English,Classid from CJ group by Classid order by English desc

出现这个错误,应该就明白了其实数据库的查询顺序是先分组的,最后才将结果进行排序。通过正常逻辑思考,通过班级分组,不就是分了三个组:班级1,班级2,班级3 。我们可以通过聚合函数查询出,每个组的个数,平均值等。可是你后面跟了英语成绩什么鬼?分组之后意味着,我们不能查询单个的记录了,我们查询的单位都是关于组的信息。

第一种实现 1

SELECT * FROM CJ m
 where(
 select COUNT(*) from CJ n
     where m.Classid = n.Classid and n.English > m.English)<2
	 order by Classid, English desc

  也是当网上查的,可以这样理解,要找出前两名的成绩,只要符合比你成绩高的不超过2个人就行了。其实是一个表的自连接,where条件就是一条一条记录对比,首先在m表中拿一条记录,是否符合 在同一班级中 比你成绩高的不超过2个人。这样就可以找到每个班的前两名成绩。然后按照降序排列。

在这种实现中,也可以加上其他筛选条件 比如查询每个班级女生中英语成绩前两名的记录

SELECT * FROM (select * from CJ where Gender=‘女‘) m
 where(
 select COUNT(*) from (select * from CJ where Gender=‘女‘) n
     where m.Classid = n.Classid and n.English > m.English)<2
     order by Classid, English desc

SELECT * FROM CJ m
 where(
 select COUNT(*) from CJ n
     where m.Classid = n.Classid and n.English > m.English and n.Gender=‘女‘)<2   --指的是内表
and Gender=‘女‘  --指的是外表
     order by Classid, English desc

第二种是实现

select a.Classid,a.English from
(select Classid,English,row_number() over(partition by Classid order by English desc) as n
from CJ) a
where n<=2

最官方,最好的实现方式

简单的说row_number()从1开始,为每一条分组记录返回一个数字

row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)

同样的加上条件

select a.Classid,a.English,n,test from
(select Classid,English,row_number() over(partition by Classid order by English desc) as n,123 test
from CJ where CJ.Gender=‘女‘) a
where n<=2

可以看出先执行的是where 进行筛选后,再通过分组,组内再排序,排序后在添加编号,其实是和正常的执行顺序一样的,只不过位置变了

原文地址:https://www.cnblogs.com/hxfcodelife/p/10226934.html

时间: 2024-10-07 13:43:45

SQL实现group by 分组后组内排序的相关文章

sql 分组后 组内排名

语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN) 简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序以后的没条xlh记录返回一个序号. 示例: xlh           row_num 1700              1 1500              2 1085             

group by分组后对组内数据进行排序

查询 每个班级英语成绩最高的前两名的记录 原文:https://www.cnblogs.com/hxfcodelife/p/10226934.html select a.Classid,a.English from (select Classid,English,row_number() over(partition by Classid order by English desc) as n from CJ) a where n<=2 另外一种情况:取组内最新的数据select max(cre

SQL group by 分组后,同一组的排序后取第一条

SELECT * FROM(                SELECT                     [SPID]                    ,[PH1]                    ,[PH1_Code]                    ,[ProjectName]                     ,ROW_NUMBER() OVER(PARTITION BY [SPID] ORDER BY [SPID]) RowNum             

MySQL中group_concat函数 --- 很有用的一个用来查询出所有group by 分组后所有 同组内的 内容

本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) 基本查询 mysql> select * from aa; +------+------+ | id| name | +------+------+ |1 |

MySql 分组并且组内排序

表如下: CREATE TABLE `asset_change_log` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',  `asset_id` int(11) unsigned NOT NULL COMMENT '资产ID',  `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态1入库2出库3借出4归还',  `ctime` datetime N

润乾集算报表非常规统计之组内排序

报表开发中,经常会碰到一些需要进行非常规统计的报表,预置分组.可重复分组.组内排序,还包括跨行组计算的报表,甚至有些报表本身无数据来源.以及需要对数据源再计算.这些报表本身具备一定的特殊性,使用常规方法往往难于实现. 而集算报表在完成这类特殊统计报表时则比较简单,这里来看下使用集算报表完成组内排序报表的实现过程. 报表说明 根据销售管理系统数据统计某年客户所在地区的订单总额,地区并按订单总额降序排列,要求每个地区中显示销售额在前五名的销售人员及其订单数量和订单金额,其他人员归入"其他"

SQL Server 分组后取Top N

SQL Server 分组后取Top N(转) 近日,工作中突遇一需求:将一数据表分组,而后取出每组内按一定规则排列的前N条数据.乍想来,这本是寻常查询,无甚难处.可提笔写来,终究是困住了笔者好一会儿.冥思苦想,遍查网络,不曾想这竟然是SQL界的一个经典话题.今日将我得来的若干方法列出,抛砖引玉,以期与众位探讨. 正文之前,对示例表结构加以说明. 表SectionTransactionLog,用来记录各部门各项活动的日志表 SectionId,部门Id SectionTransactionTyp

mysql 怎么查询出,分组后的总条数。。。也就是有多少组数。。。。怎么写

SELECT COUNT(*) AS 多少组数FROM( SELECT id FROM 表 GROUP BY id) subQuery;Mysql,有一个表含有以下字段,uid 发帖人id,title 发帖标题,tc 发帖内容,time 发帖时间,用一条语句算出昨天发帖书大于10的,一共有多少人? select count(*) from (select distinct startperson_id,count(startperson_id) as num from apphome_finan

group_concat(&#39;fanme&#39;)函数 group by id 把分组后的fname 都查出来 结果以 &quot;&quot;张三,李四,王五&quot;&quot;

group_concat函数详解 博客分类: SQL MySQLSQL 问了好多人,都不知道group_concat这个函数. 这个函数好啊,能将相同的行组合起来,省老事了. MySQL中group_concat函数 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) 基本查询 Sql代码   select * from aa; +------+------+| id| name