zoukankan      html  css  js  c++  java
  • 分组取前N记录 [转]

    原文链接:http://blog.csdn.net/acmain_chm/article/details/4126306

    经常看到问题,如何取出每组的前N条记录。方便大家参考于是便把常见的几种解法列出于下。
    
    问题:有表 如下,要求取出各班前两名(允许并列第二)
    Table1
    +----+------+------+-----+
    | id |SName |ClsNo |Score|
    +----+------+------+-----+
    |  1 |AAAA  |  C1  | 67  |
    |  2 |BBBB  |  C1  | 55  |
    |  3 |CCCC  |  C1  | 67  |
    |  4 |DDDD  |  C1  | 65  |
    |  5 |EEEE  |  C1  | 95  |
    |  6 |FFFF  |  C2  | 57  |
    |  7 |GGGG  |  C2  | 87  |
    |  8 |HHHH  |  C2  | 74  |
    |  9 |IIII  |  C2  | 52  |
    | 10 |JJJJ  |  C2  | 81  |
    | 11 |KKKK  |  C2  | 67  |
    | 12 |LLLL  |  C2  | 66  |
    | 13 |MMMM  |  C2  | 63  |
    | 14 |NNNN  |  C3  | 99  |
    | 15 |OOOO  |  C3  | 50  |
    | 16 |PPPP  |  C3  | 59  |
    | 17 |QQQQ  |  C3  | 66  |
    | 18 |RRRR  |  C3  | 76  |
    | 19 |SSSS  |  C3  | 50  |
    | 20 |TTTT  |  C3  | 50  |
    | 21 |UUUU  |  C3  | 64  |
    | 22 |VVVV  |  C3  | 74  |
    +----+------+------+-----+
    结果如下
    +----+------+------+-----+
    | id |SName |ClsNo |Score|
    +----+------+------+-----+
    |  5 |EEEE  |  C1  | 95  |
    |  1 |AAAA  |  C1  | 67  |
    |  3 |CCCC  |  C1  | 67  |
    |  7 |GGGG  |  C2  | 87  |
    | 10 |JJJJ  |  C2  | 81  |
    | 14 |NNNN  |  C3  | 99  |
    | 18 |RRRR  |  C3  | 76  |
    +----+------+------+-----+
    
    方法一:
    select a.id,a.SName,a.ClsNo,a.Score
    from Table1 a left join Table1 b on a.ClsNo=b.ClsNo and a.Score<b.Score
    group by a.id,a.SName,a.ClsNo,a.Score
    having count(b.id)<2
    order by a.ClsNo,a.Score desc
    
    方法二:
    
    select *
    from Table1 a
    where 2>(select count(*) from Table1 where ClsNo=a.ClsNo and Score>a.Score)
    order by a.ClsNo,a.Score desc
    
     
    
    方法三:
    select *
    from Table1 a
    where id in (select id from Table1 where ClsNo=a.ClsNo order by Score desc limit 2)
    order by a.ClsNo,a.Score desc
    
     
    
    方法....
    
    这里列出了多种SQL语句的实现方法,有些是MySQL特有的(Limit, 其它数据库可根据实际更改,比如oracle的rownum,MS SQL SERVER 的 top,..),有时是SQL标准支持的。但效率上和应用的场合或许不同。具体应用时可根据实际表中的记录情况,索引情况进行选择。
    
     
    
     
    
    特例 N=1 ,即取最大的/最小的一条记录。
    +----+------+------+-----+
    | id |SName |ClsNo |Score|
    +----+------+------+-----+
    |  5 |EEEE  |  C1  | 95  |
    |  7 |GGGG  |  C2  | 87  |
    | 14 |NNNN  |  C3  | 99  |
    +----+------+------+-----+
    
    
    select * 
    from Table1 a
    where not exists (select 1 from Table1 where ClsNo=a.ClsNo and Score>a.Score);
    
    select a.* 
    from Table1 a inner join (select ClsNo, max(Score) as mScore from Table1 group by ClsNo) b
     on a.ClsNo=b.ClsNo and a.Score=b.Score
    
    select *
    from (select * from Table1 order by Score desc) t
    group by ClsNo
  • 相关阅读:
    ubuntu安装openssh-server 报依赖错误的解决过程
    用 Scikit-Learn 和 Pandas 学习线性回归
    python 10分钟入门pandas
    (转)梯度下降法及其Python实现
    pandas处理日期时间,按照时间筛选
    谁动了我的特征?——sklearn特征转换行为全记录
    使用sklearn做单机特征工程
    罗技鼠标黑科技
    怎样给 VS 更换皮肤
    SQLSERVER存储过程基本语法
  • 原文地址:https://www.cnblogs.com/zuoxingyu/p/2966051.html
Copyright © 2011-2022 走看看