论坛首页 编程语言技术论坛

查出某个字段的最大记录和前N条记录

浏览 4187 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-04-09  

        经常会有查询数据库最大的记录或者前N条记录,根据某个字段分组。自己整理如下。

        数据如下:

 

id      kc      xh       score  

------  ------  ------  --------

1       语文      0023          70

2       语文      0024          76

3       语文      0025          68

4       数学      0023          15

5       数学      0024          68

6       数学      0025          95

7       数学      0026          73

8       英语      0023          77

9       英语      0024          69

10      英语      0025          12

11      英语      0026          54

12      语文      0026          34

13      物理      0023          99

14      化学      0023          89

     1、 要求查询分数最大的几个方法。结果如下:

 

id      kc      xh       score  

------  ------  ------  --------

2       语文      0024          76

6       数学      0025          95

8       英语      0023          77

13      物理      0023          99

14      化学      0023          89

      一、排除法

SELECT * FROM s_score a WHERE NOT EXISTS (SELECT 1 FROM s_score b WHERE a.kc=b.kc AND a.score<b.score);

 

     这个是用到exists,也是最容易想到的。

 

    二、内连接分组法

SELECT a.* FROM s_score a INNER JOIN (SELECT MAX(score) score,kc FROM s_score GROUP BY kc) b ON a.kc=b.kc AND a.score=b.score;

 

      这个则是先查询出每科最多的分数,然后内连接关联找出

 

    三、临时表分组法

SELECT * FROM (SELECT * FROM s_score ORDER BY score DESC ) t GROUP BY kc;

 

这个也很简单,先排序,再分组。

 

 

      2、要求分数在前2名的学科和学号,结果如下

id      kc      xh       score  

------  ------  ------  --------

14      化学      0023          89

6       数学      0025          95

7       数学      0026          73

13      物理      0023          99

8       英语      0023          77

9       英语      0024          69

2       语文      0024          76

1       语文      0023          70

 

    

      一、左连接having排除法

SELECT a.* FROM s_score a LEFT JOIN s_score b ON a.kc=b.kc AND a.score<b.score GROUP BY a.id,a.kc,a.xh,a.score HAVING COUNT(b.id)<2 ORDER BY a.kc,a.score DESC;

 

这个要先理解,理解了还是挺容易的。a会跟b的每一条比较,找处a分数小于b的,那只有第二名的分数小于第一名,然后第一名是不会小于b表中任何记录的。但是是左连接,所以结果就是前两面的记录了。

 

     二、count排除法

SELECT * FROM s_score a WHERE 2>(SELECT COUNT(*) FROM s_score b WHERE a.kc=b.kc AND a.score<b.score) ORDER BY a.kc,a.score DESC;

 

      这个原因和上面的差不多。count小于2,会有0和1,为0的情况是a中最多的分数,为1是a中第二大,b中分数最大。

 

 

参考一下:http://blog.csdn.net/acmain_chm/article/details/4126306

     

 

   发表时间:2013-04-12   最后修改:2013-04-12
引用

    三、临时表分组法
SELECT * FROM (SELECT * FROM s_score ORDER BY score DESC ) t GROUP BY kc;

这个也很简单,先排序,再分组。


这个我真是没看懂..
语法错误且不说..
就是分组完了,难道不需要再通过join或子查询获取全部字段值了吗?那如此跟文中"二、内连接分组法"有多大区别?除了多一个ORDER BY比较麻烦之外...

=========================分割线===========================

我查了一下,居然这是mysql对group by的拓展..好吧,是我无知了..抱歉啊..
不过还是建议LZ加点特别说明,毕竟还是有人不熟悉mysql的,比如我.. 
0 请登录后投票
   发表时间:2013-04-27  
joaboo 写道
引用

    三、临时表分组法
SELECT * FROM (SELECT * FROM s_score ORDER BY score DESC ) t GROUP BY kc;

这个也很简单,先排序,再分组。


这个我真是没看懂..
语法错误且不说..
就是分组完了,难道不需要再通过join或子查询获取全部字段值了吗?那如此跟文中"二、内连接分组法"有多大区别?除了多一个ORDER BY比较麻烦之外...

=========================分割线===========================

我查了一下,居然这是mysql对group by的拓展..好吧,是我无知了..抱歉啊..
不过还是建议LZ加点特别说明,毕竟还是有人不熟悉mysql的,比如我.. 

  这个mysql上的group by 和oracle上的确实不同,oracle中select不能出现没在group by中的列。mysql却可以。
  这内链接分组法还是差别很大的,内链接分组是先找处每科最大的分数,然后再根据学科和分数关联找处所有信息。
   临时表分组法是先对分数分降序分组,再根据学科分组。
  
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics