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

和自甴很熟 提交于 2019-12-07 13:26:21

不同的数据库类型有不同的方法,这取决于每种数据库都有自己独有的内置方法。但也有通用sql实现的方法。

测试实例如下,环境mysql。

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中最大值。

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中均测试过,没有问题。

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

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> 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!