不同的数据库类型有不同的方法,这取决于每种数据库都有自己独有的内置方法。但也有通用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>
来源:oschina
链接:https://my.oschina.net/u/2342410/blog/759388