不一樣的數據庫類型有不一樣的方法,這取決於每種數據庫都有本身獨有的內置方法。但也有通用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>