• MySQL取每组的前N条记录


    一、对分组的记录取前N条记录:例子:取前 2条最大(小)的记录

     1 1.用子查询:
     2 SELECT * FROM right2 a  WHERE 2>
     3 (SELECT COUNT(*) FROM right2 b WHERE b.id=a.id AND b.account>a.account)
     4 ORDER BY a.id,a.account DESC
     5 2.用exists半连接:
     6 SELECT * FROM right2 a  WHERE EXISTS
     7 (SELECT COUNT(*) FROM right2 b WHERE b.id=a.id AND a.account<b.account HAVING COUNT(*)<2)
     8 ORDER BY a.id,a.account DESC
     9 同理可以取组内最小的N条记录:
    10 SELECT * FROM right2 a  WHERE 2>
    11 (SELECT COUNT(*) FROM right2 b WHERE b.id=a.id AND b.account<a.account)
    12 ORDER BY a.id,a.account DESC
    13 用exists:
    14 SELECT * FROM right2 a  WHERE EXISTS
    15 (SELECT COUNT(*) FROM right2 b WHERE b.id=a.id AND a.account>b.account HAVING COUNT(*)<2)
    16 ORDER BY a.id,a.account DESC

     如果取每组的最大(小)一条记录我常用:

    select t1.* from table t inner join(select * from table t1 order by id desc) t1 on t.id=t1.id group by t.id order by t.id; //一定用t1.*,用t.*不OK

    二.实例:取每组最大的前 N条

     1 create table t2 (
     2   id int primary key,       
     3   gid char, 
     4   col1 int, 
     5   col2 int  
     6 ) engine=innodb; 
     7 insert into tx01 values
     8 (1,'A',31,6), 
     9 (2,'B',25,83), 
    10 (3,'C',76,21), 
    11 (4,'D',63,56), 
    12 (5,'E',3,17), 
    13 (6,'A',29,97), 
    14 (7,'B',88,63), 
    15 (8,'C',16,22), 
    16 (9,'D',25,43), 
    17 (10,'E',45,28), 
    18 (11,'A',2,78), 
    19 (12,'B',30,79), 
    20 (13,'C',96,73), 
    21 (14,'D',37,40), 
    22 (15,'E',14,86), 
    23 (16,'A',32,67), 
    24 (17,'B',84,38), 
    25 (18,'C',27,9), 
    26 (19,'D',31,21), 
    27 (20,'E',80,63), 
    28 (21,'A',89,9), 
    29 (22,'B',15,22), 
    30 (23,'C',46,84), 
    31 (24,'D',54,79), 
    32 (25,'E',85,64), 
    33 (26,'A',87,13), 
    34 (27,'B',40,45), 
    35 (28,'C',34,90), 
    36 (29,'D',63,8), 
    37 (30,'E',66,40), 
    38 (31,'A',83,49), 
    39 (32,'B',4,90), 
    40 (33,'C',81,7), 
    41 (34,'D',11,12), 
    42 (35,'E',85,10), 
    43 (36,'A',39,75), 
    44 (37,'B',22,39), 
    45 (38,'C',76,67), 
    46 (39,'D',20,11), 
    47 (40,'E',81,36); 
    48 create table tx01 (
    49   id int primary key, 
    50   gid char, 
    51   col1 int, 
    52   col2 int  
    53 ) engine=innodb;

    取每组gid 最大的前N条记录:使用自连接或则半连接

    *N=1时:

    自连接:降序排好后group by取每组最大的一条。

    select * from (select * from t2 order by col2 desc)as a group by gid order by gid;

    半连接方式:找不到比最大值还大的。

    select * from t2 a where not exists(select 1 from t2 b where b.gid=a.gid and b.col2>a.col2) order by a.gid; 

    *N=3时:

    自连接:

    select * from t2 a where 3>(select count(*) from t2 where gid=a.gid and col2>a.col2) order by a.gid,a.col2 desc;

    半连接:

    select * from t2 a where exists(select count(*) from t2 b where b.gid=a.gid and a.col2<b.col2 having(count(*))<3) order by a.gid,a.col2 desc

    转:本文出自 http://huanghualiang.blog.51cto.com/6782683/1252630

  • 相关阅读:
    显卡关键词
    为照顾IE6尽量不要margin和padding
    如何保证一个类只有一个实例(1)
    显示列表(display list)
    AutoCAD2007与Office2007冲突
    虚函数(1)
    字符串对象的属性
    细读cow.osg
    常量折叠(const folding)与复写传播 (copy propagation)
    .NET Framework 3.5 sp1离线安装
  • 原文地址:https://www.cnblogs.com/leezhxing/p/4392283.html
Copyright © 2020-2023  润新知