关闭

sql分组后查找每组的前几条记录语句

1089人阅读 评论(0) 收藏 举报
分类:

常用的sqlserver,mysql,oracle等数据库sql语句都是遵循sql标准,但是每种数据库都有自己的特点。

如果想做到程序兼容性更好,后期维护更方便,还是建议尽量使用各种数据库通用的sql语句(当然你也可以使用数据库独有特性)。

这里举个看似简单,缺难道不少人的例子:

分组查询每个班级分数前2名学生的记录

1.准备数据:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `NAME` varchar(10) default NULL,
  `class` varchar(20) default NULL,
  `score` varchar(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `test` VALUES ('1', '进一', '09-01', '299');
INSERT INTO `test` VALUES ('2', '虹二', '09-01', '259');
INSERT INTO `test` VALUES ('3', '张三', '09-01', '289');
INSERT INTO `test` VALUES ('4', '李四', '09-01', '277');
INSERT INTO `test` VALUES ('5', '张楚', '09-02', '287');
INSERT INTO `test` VALUES ('6', '小米', '09-02', '277');
INSERT INTO `test` VALUES ('7', '婷婷', '09-02', '257');
INSERT INTO `test` VALUES ('8', '月月', '09-02', '265');

2.查询分析
按class分组,然后取id靠前的两名,相信大多数人都能想到基本组合:
SELECT a.* FROM test a ORDER BY a.class, a.score;
注:sqlserver中可以用top n的写法,mysql中用limit 0 ,n,那么oracle中又得变了。
并且top0,n和Limit 0,n只能取到最前的n位,但如何能取到每个班的前n位呢,就无从下手了。
下面具体分析一下这题的解法:
获取每个class的前2位:
SELECT * FROM test a WHERE (SELECT COUNT(*) FROM test t WHERE t.class = a.class AND t.score > a.score) < 2;
遍历所有记录a,a.class
每条记录进行如下对比:
同班t,t.class=a.class 且分数比他高(score大于他)的记录的条数<2
(比他分数高的人的数量小于2;比他分数高的人有1个,他是第2名;比他分数高的人有0个,他是第1名;所以筛选出来的是前2名)
然后用该条记录与同班t中的所有记录比较,只有当班上t不超过两个人(含两个人)比该记录score高的话,该记录才被认定为该记录score排名前2,然后显示出来。






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6774次
    • 积分:115
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:4篇
    • 译文:1篇
    • 评论:2条
    文章分类
    最新评论