效率最快:
此方法Oracle和SQL Server2005通用。

select id,name,class,date from(
 select id,name,class,date ,row_number() over(partition by class order by date desc)
 as rowindex from table1)a
 where rowindex<=5其中 class是类别字段
rowindex<=5 取出前5
其他通用方法:
数据如下:
 name val memo
 a    2   a2(a的第二个值)
 a    1   a1--a的第一个值
 a    3   a3:a的第三个值
 b    1   b1--b的第一个值
 b    3   b3:b的第三个值
 b    2   b2b2b2b2
 b    4   b4b4
 b    5   b5b5b5b5b5
 */
 --创建表并插入数据:
 create table tb(name varchar(10),val int,memo varchar(20))
 insert into tb values('a',    2,   'a2(a的第二个值)')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('b',    1,   'b1--b的第一个值')
 insert into tb values('b',    3,   'b3:b的第三个值')
 insert into tb values('b',    2,   'b2b2b2b2')
 insert into tb values('b',    4,   'b4b4')
 insert into tb values('b',    5,   'b5b5b5b5b5')
 go--一、按name分组取val最大的值所在行的数据。
 --方法1:
 select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
 --方法2:
 select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
 --方法3:
 select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
 --方法4:
 select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
 --方法5
 select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          3           a3:a的第三个值
 b          5           b5b5b5b5b5
 */--二、按name分组取val最小的值所在行的数据。
 --方法1:
 select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
 --方法2:
 select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
 --方法3:
 select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
 --方法4:
 select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
 --方法5
 select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          1           a1--a的第一个值
 b          1           b1--b的第一个值
 */--三、按name分组取第一次出现的行所在的数据。
 select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          2           a2(a的第二个值)
 b          1           b1--b的第一个值
 */--四、按name分组随机取一条数据。
 select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          1           a1--a的第一个值
 b          5           b5b5b5b5b5
 */--五、按name分组取最小的两个(N个)val
 select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
 select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
 select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          1           a1--a的第一个值
 a          2           a2(a的第二个值)
 b          1           b1--b的第一个值
 b          2           b2b2b2b2
 */--六、按name分组取最大的两个(N个)val
 select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
 select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
 select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          2           a2(a的第二个值)
 a          3           a3:a的第三个值
 b          4           b4b4
 b          5           b5b5b5b5b5
 */
 --七,如果整行数据有重复,所有的列都相同。
 /*
 数据如下:
 name val memo
 a    2   a2(a的第二个值)
 a    1   a1--a的第一个值
 a    1   a1--a的第一个值
 a    3   a3:a的第三个值
 a    3   a3:a的第三个值
 b    1   b1--b的第一个值
 b    3   b3:b的第三个值
 b    2   b2b2b2b2
 b    4   b4b4
 b    5   b5b5b5b5b5
 */
 --在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
 --创建表并插入数据:
 create table tb(name varchar(10),val int,memo varchar(20))
 insert into tb values('a',    2,   'a2(a的第二个值)')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('b',    1,   'b1--b的第一个值')
 insert into tb values('b',    3,   'b3:b的第三个值')
 insert into tb values('b',    2,   'b2b2b2b2')
 insert into tb values('b',    4,   'b4b4')
 insert into tb values('b',    5,   'b5b5b5b5b5')
 goselect * , px = identity(int,1,1) into tmp from tb
select m.name,m.val,m.memo from
 (
 select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
 ) m where px = (select min(px) from
 (
 select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
 ) n where n.name = m.name)drop table tb,tmp
/*
 name       val         memo
 ---------- ----------- --------------------
 a          1           a1--a的第一个值
 b          1           b1--b的第一个值(2 行受影响)
 */
 --在sql server 2005中可以使用row_number函数,不需要使用临时表。
 --创建表并插入数据:
 create table tb(name varchar(10),val int,memo varchar(20))
 insert into tb values('a',    2,   'a2(a的第二个值)')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('b',    1,   'b1--b的第一个值')
 insert into tb values('b',    3,   'b3:b的第三个值')
 insert into tb values('b',    2,   'b2b2b2b2')
 insert into tb values('b',    4,   'b4b4')
 insert into tb values('b',    5,   'b5b5b5b5b5')
 goselect m.name,m.val,m.memo from
 (
 select * , px = row_number() over(order by name , val) from tb
 ) m where px = (select min(px) from
 (
 select * , px = row_number() over(order by name , val) from tb
 ) n where n.name = m.name)drop table tb
/*
 name       val         memo
 ---------- ----------- --------------------
 a          1           a1--a的第一个值
 b          1           b1--b的第一个值(2 行受影响)
 还有数据如下:
 name val memo
 a    2   a2(a的第二个值)
 a    1   a1--a的第一个值
 a    3   a3:a的第三个值
 b    1   b1--b的第一个值
 b    3   b3:b的第三个值
 b    2   b2b2b2b2
 b    4   b4b4
 b    5   b5b5b5b5b5
 */
 --创建表并插入数据:
 create table tb(name varchar(10),val int,memo varchar(20))
 insert into tb values('a',    2,   'a2(a的第二个值)')
 insert into tb values('a',    1,   'a1--a的第一个值')
 insert into tb values('a',    3,   'a3:a的第三个值')
 insert into tb values('b',    1,   'b1--b的第一个值')
 insert into tb values('b',    3,   'b3:b的第三个值')
 insert into tb values('b',    2,   'b2b2b2b2')
 insert into tb values('b',    4,   'b4b4')
 insert into tb values('b',    5,   'b5b5b5b5b5')
 go--五、按name分组取最小的两个(N个)val
 select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
 select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
 select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          1           a1--a的第一个值
 a          2           a2(a的第二个值)
 b          1           b1--b的第一个值
 b          2           b2b2b2b2
 */--六、按name分组取最大的两个(N个)val
 select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
 select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
 select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name
 /*
 name       val         memo                 
 ---------- ----------- -------------------- 
 a          2           a2(a的第二个值)
 a          3           a3:a的第三个值
 b          4           b4b4
 b          5           b5b5b5b5b5
 */-------------------------------------
SQL语句写法有4种。
1.SQL2005,情况下使用 行号 Row_Number()
SELECT * 
 FROM 
 ( 
 SELECT ROW_NUMBER() OVER(PARTITION BY ct ORDER BY name) AS rnk,* 
 FROM tb_name 
 ) AS t 
 WHERE rnk<=3讲解:用ROW_NUMBER() 以ct字段划分表数据,为每行数据添加行号。
 然后从这个结果集里查询出行号小于等于3的记录,就是每类的前3条记录。2.使用 CROSS APPLY
SELECT DISTINCT b.* 
 FROM tb_name AS a 
 CROSS APPLY 
 ( 
 SELECT TOP 3 * 
 FROM tb_name 
 WHERE a.ct=ct 
 ) AS b ORDER BY b.ct讲解:主要利用CROSS APPLY,这类似join.
首先在子查询里查询出表里每类的前3条记录,然后利用CROSS APPLY 和 DISTINCT ,把查询里相同的记录过滤掉。
 就是前3条记录了。

 不过这样的效率很低,不推荐使用。

 3. 利用子查询SELECT * 
 FROM tb_name AS t 
 WHERE 3>(SELECT COUNT(*) 
 FROM tb_name 
 WHERE ct=t.ct 
 AND name>t.name);讲解:关键是子查询,这里类似一个while循环,每条记录去匹配和它同类的下一条记录。
 计算以它开始算起记录条数,意思就是他当前所在的行号,当行号小于3的时候,证明他下面有至多3条记录,则符合子查询条件,返回到结果集里。
 这样就查询出了每类的前3条记录。

 4.使用checksum函数(数据有重复时特别好用)先是取每类的前3条记录,然后在结果集里用in最终取出结果。

 select * from @t a 
 where checksum(*) in (select top 3 checksum(*) from @t b where a.ct=b.ct order by name desc)示例:
if object_id('tempdb.dbo.#db')
 drop table #tb
 create table #tb(id int identity,name varchar(10),val int,memo varchar(20));
 insert into #tb(name,val,memo) values('a',    1,   'a1--a的第一个值');
 insert into #tb(name,val,memo) values('a',    2,   'a2(a的第二个值)');
 insert into #tb(name,val,memo) values('a',    3,   'a3:a的第三个值');insert into #tb(name,val,memo) values('b',    1,   'b1--b的第一个值');
 insert into #tb(name,val,memo) values('b',    2,   'b2b2b2b2');
 insert into #tb(name,val,memo) values('b',    3,   'b3:b的第三个值');
 insert into #tb(name,val,memo) values('b',    4,   'b4b4');
 insert into #tb(name,val,memo) values('b',    5,   'b5b5b5b5b5');(1)一步到位
 select * --into #tb1
 from #tb a 
 where checksum(*) in (select top 5 checksum(*) from #tb b where a.name=b.name order by b.val desc,b.memo desc)
 order by a.name,a.val desc(2)创建临时表(大数据量使用)
 (a)取出每个分类排名前N的记录
 if object_id('tempdb.dbo.#db1')
 drop table #tb1
 select * --into #tb1
 from #tb a 
 where (
 select count(*) from #tb b where a.name=b.name and a.val<b.val and a.memo<b.memo)<5 
 order by a.name,a.val desc(b)取出每个分类前N条记录
 select * from #tb1 a where checksum(*) in (select top 5 checksum(*) from #tb1 b where a.name=b.name)