在一个月黑风高的夜晚,自己无聊学习的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 进行筛选后,再通过分组,组内再排序,排序后在添加编号,其实是和正常的执行顺序一样的,只不过位置变了

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

  1. SQL,group by分组后分别计算组内不同值的数量

    select name as 姓名,sum( case when cargo='笔' then 1 else 0 end ) as 笔,sum( case when cargo='橡皮' then 1 ...

  2. sql 用Group by分组后,取每组的前几条记录

    转自:http://blog.163.com/jeson_lwj/blog/static/135761083201052411115783/ --查询每门课程的前2名成绩 CREATE TABLE S ...

  3. Sql示例说明如何分组后求中间值--【叶子】

    原文:Sql示例说明如何分组后求中间值--[叶子] 这里所谓的分组后求中间值是个什么概念呢? 我举个例子来说明一下: 假设我们现在有下面这样一个表: type        name price -- ...

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

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

  5. group by 分组后 返回的是一个同属性的集合

    group by 分组后 返回的是一个同属性的集合  我们可以遍历该集合

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

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

  7. group by 查询分组后 组的条数

    比如select gid from table group by gid 查询时使用下面的方法查询条数 select count(distinct gid) from table 使用select c ...

  8. sql的 group by 分组;linq的 group by 分组

    先来看看 linq的,下面的一段linq 是 ,在 学生导入数据的时候,我们根据学生的手机号码和学生名称进行分组,如果有重复的,我们就筛选出来,用到了 linq的 group by,注意这里是new出 ...

  9. GROUP BY 分组后得到最新即时间最大的一条数据(需添加limit才可生效)

    当使用GROUP BY 分组,默认返回的数据是组中最小的记录即id最小的数据, 当开发中经常会需要分组后将最新的数据放在前面, 为了实现需求,使用了嵌套查询,分别使用order by来排序 SELEC ...

随机推荐

  1. FatMouse's Speed HDU - 1160 最长上升序列, 线性DP

    #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> usi ...

  2. 莫凡_linux

    1.安装软件 2.基本命令ls和cd cd 指令 第一个要知道的指令就是怎么样去到你想去的地方. cd (Change Directory) 就是干这个的. 找到 Linux 的 terminal 窗 ...

  3. Latex中遇到 No room for a new \count 问题的解决

    在tex文件中加入etex宏包. \usepackage{etex} 最好加载第一个宏包位置 PDF合并 \documentclass[a4paper]{article}\usepackage{pdf ...

  4. 心里没点B树,怎能吃透数据库索引底层原理?

    二叉树(Binary Search Trees) 二叉树是每个结点最多有两个子树的树结构.通常子树被称作“左子树”(Left Subtree)和“右子树”(Right Subtree).二叉树常被用于 ...

  5. linux分区命令parted的用法

    parted的适用场景 创建操作大于2T的分区 一般情况下,我们都是选择使用fdisk工具来进行分区,但是目前在实际生产环境中使用的磁盘空间越来越大,呈TiB级别增长:而常用的fdisk这个工具对分区 ...

  6. 二分-A - Cable master

    A - Cable master Inhabitants of the Wonderland have decided to hold a regional programming contest. ...

  7. 白面系列 redis

    redis是Key-Value数据库,和Memcached类似.value可以是多种类型,如Strings, Lists, Hashes, Sets 及 Ordered Sets等. redis一个牛 ...

  8. Manacher算法求最长回文串模板

    #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> ...

  9. 问题解决:局域网内,为啥别人ping不到我的IP

    试着在本地搭建一个测试环境,成功后却发现同一局域网的同事根本访问不了,他们ping不到我的IP,这可咋整! 询问度娘后,我的问题得到了,以下是我的总结,如果解决不了你的问题,还请继续百度. 方法一:关 ...

  10. shiro认证和授权

    一.shiro基础概念 Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份: Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户 ...