不一样的数据库类型有不一样的方法,这取决于每种数据库都有本身独有的内置方法。但也有通用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>