create table #tb ( [name] varchar(20), [date] datetime )insert into #tb select 'A','2009-01-05' union all select 'A','2009-03-26' union all select 'A','2010-05-25' union all select 'B','2009-01-06' union all select 'B','2009-06-25' union all select 'B','2009-08-05' union all select 'B','2009-10-16' union all select 'C','2009-02-05' union all select 'C','2010-01-15' union all select 'D','2008-01-05' union all select 'D','2009-02-16' union all select 'D','2009-03-05' union all select 'D','2009-05-27' union all select 'D','2009-09-05' union all select 'D','2010-07-15' select name,datepart(year,date) year ,count(*) num from #tb group by name,datepart(year,date) order by datepart(year,date),count(*) descname year num -------------------- ----------- ----------- D 2008 1 B 2009 4 D 2009 4 A 2009 2 C 2009 1 A 2010 1 C 2010 1 D 2010 1(8 行受影响)
select top 5 name,datepart(year,date) year ,count(*) num from #tb where datepart(year,date) = 2010 group by name,datepart(year,date) order by datepart(year,date),count(*) desc你可以把写个存储过程,把2010换成一个变量。 或者你还是像原来那样,在你程序里面过滤
create proc test_proc declare @year int as begin select top 5 name,datepart(year,date) year ,count(*) num from tb where datepart(year,date) = @year group by name,datepart(year,date) order by datepart(year,date),count(*) desc end
create table #tb ( [name] varchar(20), [date] datetime )insert into #tb select 'A','2009-01-05' union all select 'A','2009-03-26' union all select 'A','2010-05-25' union all select 'B','2009-01-06' union all select 'B','2009-06-25' union all select 'B','2009-08-05' union all select 'B','2009-10-16' union all select 'C','2009-02-05' union all select 'C','2010-01-15' union all select 'D','2008-01-05' union all select 'D','2009-02-16' union all select 'D','2009-03-05' union all select 'D','2009-05-27' union all select 'D','2009-09-05' union all select 'D','2010-07-15' declare @year int,--年度 @rnk int --每个分组排名前n,相同的排名也显示
select @year =2009,@rnk=3;with t as ( select rn=DENSE_RANK()over(PARTITION BY Name order by date desc),* from #tb where date >= DATEADD(yy,@year-1900,0) and date < DATEADD(yy,@year-1900+1,0) ) select * from t where rn<=@rnk /* rn name date -------------------- -------------------- ----------------------- 1 A 2009-03-26 00:00:00.000 2 A 2009-01-05 00:00:00.000 1 B 2009-10-16 00:00:00.000 2 B 2009-08-05 00:00:00.000 3 B 2009-06-25 00:00:00.000 1 C 2009-02-05 00:00:00.000 1 D 2009-09-05 00:00:00.000 2 D 2009-05-27 00:00:00.000 3 D 2009-03-05 00:00:00.000(9 行受影响) */一楼的测试数据
create table #tb
(
[name] varchar(20),
[date] datetime
)insert into #tb
select 'A','2009-01-05' union all
select 'A','2009-03-26' union all
select 'A','2010-05-25' union all
select 'B','2009-01-06' union all
select 'B','2009-06-25' union all
select 'B','2009-08-05' union all
select 'B','2009-10-16' union all
select 'C','2009-02-05' union all
select 'C','2010-01-15' union all
select 'D','2008-01-05' union all
select 'D','2009-02-16' union all
select 'D','2009-03-05' union all
select 'D','2009-05-27' union all
select 'D','2009-09-05' union all
select 'D','2010-07-15'
select name,datepart(year,date) year ,count(*) num
from #tb
group by
name,datepart(year,date)
order by
datepart(year,date),count(*) descname year num
-------------------- ----------- -----------
D 2008 1
B 2009 4
D 2009 4
A 2009 2
C 2009 1
A 2010 1
C 2010 1
D 2010 1(8 行受影响)
select top 5 name,datepart(year,date) year ,count(*) num
from #tb
where
datepart(year,date) = 2010
group by
name,datepart(year,date)
order by
datepart(year,date),count(*) desc你可以把写个存储过程,把2010换成一个变量。
或者你还是像原来那样,在你程序里面过滤
declare @year int
as
begin
select top 5 name,datepart(year,date) year ,count(*) num
from tb where datepart(year,date) = @year
group by name,datepart(year,date)
order by datepart(year,date),count(*) desc
end
(
[name] varchar(20),
[date] datetime
)insert into #tb
select 'A','2009-01-05' union all
select 'A','2009-03-26' union all
select 'A','2010-05-25' union all
select 'B','2009-01-06' union all
select 'B','2009-06-25' union all
select 'B','2009-08-05' union all
select 'B','2009-10-16' union all
select 'C','2009-02-05' union all
select 'C','2010-01-15' union all
select 'D','2008-01-05' union all
select 'D','2009-02-16' union all
select 'D','2009-03-05' union all
select 'D','2009-05-27' union all
select 'D','2009-09-05' union all
select 'D','2010-07-15'
declare @year int,--年度
@rnk int --每个分组排名前n,相同的排名也显示
select @year =2009,@rnk=3;with t as
(
select rn=DENSE_RANK()over(PARTITION BY Name order by date desc),*
from #tb
where date >= DATEADD(yy,@year-1900,0) and date < DATEADD(yy,@year-1900+1,0)
)
select * from t where rn<=@rnk
/*
rn name date
-------------------- -------------------- -----------------------
1 A 2009-03-26 00:00:00.000
2 A 2009-01-05 00:00:00.000
1 B 2009-10-16 00:00:00.000
2 B 2009-08-05 00:00:00.000
3 B 2009-06-25 00:00:00.000
1 C 2009-02-05 00:00:00.000
1 D 2009-09-05 00:00:00.000
2 D 2009-05-27 00:00:00.000
3 D 2009-03-05 00:00:00.000(9 行受影响)
*/一楼的测试数据
建议你列出你的表结构,并提供测试数据以及基于这些测试数据的所对应正确结果。
参考一下这个贴子的提问方式http://topic.csdn.net/u/20091130/20/8343ee6a-417c-4c2d-9415-fa46604a00cf.html
1. 你的 create table xxx .. 语句
2. 你的 insert into xxx ... 语句
3. 结果是什么样,(并给以简单的算法描述)
4. 你用的数据库名称和版本(经常有人在MS SQL server版问 MySQL)
这样想帮你的人可以直接搭建和你相同的环境,并在给出方案前进行测试,避免文字描述理解上的误差。