數據庫表分組取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>
相關文章
相關標籤/搜索