转自:http://blog.163.com/jeson_lwj/blog/static/135761083201052411115783/

--查询每门课程的前2名成绩
CREATE TABLE StudentGrade(
stuId CHAR(4), --学号
subId INT, --课程号
grade INT, --成绩
PRIMARY KEY (stuId,subId)
)
GO
--表中数据如下
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',1,97);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',2,50);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('001',3,70);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',1,92);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',2,80);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('002',3,30);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',1,93);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',2,95);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('003',3,85);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',1,73);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',2,78);
INSERT INTO StudentGrade(stuId,subId,grade) VALUES('004',3,87);
GO
/*
要查询每门课程的前2名成绩
001 1 97
003 1 93
003 2 95
002 2 80
004 3 87
003 3 85
如何实现?
*/
--查看数据
select * from StudentGrade --假如出现并列时,也只取两个同学的话。
--方法一:
select distinct *
from studentgrade as t1
where stuid in
(select top 2 stuid
from studentgrade as t2
where t1.subid=t2.subid
order by t2.grade desc)
order by subid, grade desc --方法二:
select * from StudentGrade a where (select count(1) from studentGrade where subId=a.subId and grade>=a.grade)<=2 --方法三:
select * from StudentGrade t
where (select count(1) from StudentGrade where subid=t.subid and grade>t.grade)<=1
order by subId,grade desc --结果
/*
stuId subId grade
----- ----------- -----------
001 1 97
003 1 93
003 2 95
002 2 80
004 3 87
003 3 85 (6 row(s) affected)
*/ 共有三种方案,从难易程度上讲我倾向于后两种,从查询逻辑思想上来讲后两种是一样的 select * from StudentGrade t
where (select count(1) from StudentGrade where subid=t.subid and grade>t.grade)<=1
order by subId,grade desc 我是这样理解的,看成两张表A和B,条件为A表的学科=B表的学科,select count(1) from StudentGrade where subid=t.subid and grade>t.grade,返回A表的学科=B表的学科并且A表的成绩小于B表的成绩的影响行数,如果所影响的行数为零说明它的成绩是最高的,如果等于1的话就是最高的两个成绩。这就是查询条件,再按 subId,grade 排序。这种查询思想很值得我学习

  

sql 用Group by分组后,取每组的前几条记录的更多相关文章

  1. 用Group by分组后,取每组的前3条记录,怎么取?

    使用子查询进行查询 SELECT * FROM home_content a WHERE ( SELECT count(id) FROM home_content WHERE class_link = ...

  2. sql 分组后显示每组的前几条记录

    sql 分组后显示每组的前几条记录 如   表中记录是             code       serialno             A1               1           ...

  3. MySQL取每组的前N条记录

    一.对分组的记录取前N条记录:例子:取前 2条最大(小)的记录 .用子查询: SELECT * FROM right2 a WHERE > (SELECT COUNT(*) FROM right ...

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

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

  5. 记一次有意思的 SQL 实现 → 分组后取每组的第一条记录

    开心一刻 今天,朋友气冲冲的走到我面前 朋友:我不是谈了个女朋友,谈了三个月嘛,昨天我偷看她手机,你猜她给我备注什么 我:备注什么? 朋友:舔狗 2 号! 我一听,气就上来了,说道:走,找她去,这婆娘 ...

  6. MSSQL 分组后取每组第一条(group by order by)

    查询中经常遇到这种查询,分组后取每组第一条.分享下一个SQL语句: --根据 x 分组后.根据 y 排序后取第一条 select * from ( select ROW_NUMBER() over(p ...

  7. sql 分组取每组的前n条或每组的n%(百分之n)的数据

    sql 分组取每组的前n条或每组的n%(百分之n)的数据 sql keyword: SELECT * ,ROW_NUMBER() OVER(partition by b.UserID order by ...

  8. 从排序后的结果集中删除 前n条记录

    端午有人休息,有人忙 操作前数据: --从排序后的结果集中删除 前n条记录delete from emp where empno in (select empno                   ...

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

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

随机推荐

  1. MyBatis数据库连接的基本使用

    MyBatis部分: 本部分内容只主要体现Mybatis的特点. (1)MyBatis是什么? 开源的持久层框架,MyBatis的底层仍然是JDBC (2)编程步骤 step1 Maven项目 pom ...

  2. cdnbest补充api

    1.应用防火墙---防CC 添加|修改 请求地址: {api_dir}/firewall/anticc 请求方式: PUT 请求参数: frcquency string 触发频率 例:low(低) | ...

  3. js中函数的 this、arguments 、caller,call(),apply(),bind()

    在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller. arguments对象 arguments是一个类似数组的对象,包含着传入函数的所有参数. func ...

  4. 下载安装windows版Redis

    链接       https://github.com/MicrosoftArchive/redis/releases 选择版本下载 在redis目录打开cmd命令输入 redis-server.ex ...

  5. JMeter使用中遇到的问题:Jmeter Debug - "Unrecognized VM option '+HeapDumpOnOutOfMemoryError"(转载)

    转载自 http://www.cnblogs.com/yangxia-test 启动JMeter.bat的程序时,出现以下出错信息: Unrecognized VM option '+HeapDump ...

  6. ss源码学习--从协议建立到完成一次代理请求

    上一次介绍了ss源码中各个事件处理函数完成的工作,这次具体分析一下协议的建立以及请求数据的传输过程. 因为ss的local和server共用一个类以及一系列的事件处理函数,所以看起来稍显复杂.下面来将 ...

  7. centos7安装zabbix3.5

    安装centos7 自带MariaDB数据库(或者安装mysql) yum -y install mariadb-server mariadb-devel systemctlstartmariadb. ...

  8. navicat连接虚拟机中mysql"Access denied for user'root'@'IP地址'"问题

    登陆要链接的服务器上的mysql 命令:mysql -uroot -p123456 然后执行 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED ...

  9. Fibonacci again and again

    Fibonacci again and again http://acm.hdu.edu.cn/showproblem.php?pid=1848 Time Limit: 1000/1000 MS (J ...

  10. f5会话保持

    B/S架构的建议选择 inset cookie :c/s架构的 建议选择 sorce ip 1.  Introduction to session persistence profiles Using ...