数据库表分组取top n的sql操做

不一样的数据库类型有不一样的方法,这取决于每种数据库都有本身独有的内置方法。但也有通用sql实现的方法。mysql

测试实例以下,环境mysql。sql

create table tb (a int,b int);
insert into tb values(1,15);
insert into tb values(1,53);
insert into tb values(1,21);
insert into tb values(1,12);
insert into tb values(1,77);
insert into tb values(2,32);
insert into tb values(2,8);
insert into tb values(2,29);
insert into tb values(2,75);
insert into tb values(2,46);
insert into tb values(2,81);
insert into tb values(3,65);
insert into tb values(3,17);
insert into tb values(3,59);
insert into tb values(3,26);
insert into tb values(3,43);

这里只有两列a和b。数据库

以a列分组,取b中最大值。oracle

mysql> select a,max(b) from tb group by a;
+------+--------+
| a    | max(b) |
+------+--------+
|    1 |     77 |
|    2 |     81 |
|    3 |     65 |
+------+--------+
3 rows in set (0.00 sec)

mysql>

取每组数量和平均值。函数

mysql> select a,count(b) from tb group by a;
+------+----------+
| a    | count(b) |
+------+----------+
|    1 |        5 |
|    2 |        6 |
|    3 |        5 |
+------+----------+
3 rows in set (0.00 sec)

mysql> select a,avg(b) from tb group by a;
+------+---------+
| a    | avg(b)  |
+------+---------+
|    1 | 35.6000 |
|    2 | 45.1667 |
|    3 | 42.0000 |
+------+---------+
3 rows in set (0.03 sec)

mysql>

取每组按照降序排列的top n。测试

mysql> select * from tb t1 where ( select count(distinct b) from tb t2 where t1.a=t2.a and t2.b>=t1.b )<=3 order by a,b desc;
+------+------+
| a    | b    |
+------+------+
|    1 |   77 |
|    1 |   53 |
|    1 |   21 |
|    2 |   81 |
|    2 |   75 |
|    2 |   46 |
|    3 |   65 |
|    3 |   59 |
|    3 |   43 |
+------+------+
9 rows in set (0.00 sec)

mysql>

mysql> select * from tb t1 where ( select count(distinct b) from tb t2 where t1.a=t2.a and t2.b<=t1.b )<=3 order by a,b;

+------+------+
| a    | b    |
+------+------+
|    1 |   12 |
|    1 |   15 |
|    1 |   21 |
|    2 |    8 |
|    2 |   29 |
|    2 |   32 |
|    3 |   17 |
|    3 |   26 |
|    3 |   43 |
+------+------+
9 rows in set (0.00 sec)

mysql>

以上在mysql和oracle中均测试过,没有问题。code

对于Oracle,有专门的内置函数来处理:it

SQL> select * from
  2  (select a,b,rank() over(partition by a order by b) r from tb)
  3  where r<=3
  4  ;
                                      A                                       B          R
--------------------------------------- --------------------------------------- ----------
                                      1                                      12          1
                                      1                                      15          2
                                      1                                      21          3
                                      2                                       8          1
                                      2                                      29          2
                                      2                                      32          3
                                      3                                      17          1
                                      3                                      26          2
                                      3                                      43          3
9 rows selected

SQL> 

SQL> select * from
  2  (select a,b,rank() over(partition by a order by b desc) r from tb)
  3  where r<=3
  4  ;
                                      A                                       B          R
--------------------------------------- --------------------------------------- ----------
                                      1                                      77          1
                                      1                                      53          2
                                      1                                      21          3
                                      2                                      81          1
                                      2                                      75          2
                                      2                                      46          3
                                      3                                      65          1
                                      3                                      59          2
                                      3                                      43          3
9 rows selected

SQL>
相关文章
相关标签/搜索