导航
  • 主页
  • 基础类
  • 应用实例
  • 新技术前沿

一道牛逼的数据库题目,NB的人请进

lg3605119 2007-12-12 06:06:06
凑热闹,当年公司面试题,做出来了就留下,否则走人

原始表:
姓名 金额 日期
张三 100 1998/4/8
张三 10 1998/7/4
里斯 20.5 1999/8/9
张三 10 1999/8/7
王五 30.5 1998/1/1
刘二 22.5 2000/8/4
里斯 30 2001/8/9
赵毅 2 2002/8/4
王五 14 2000/2/21
张三 52 1999/12/9
王八 33 2005/8/9
刘二 20 2007/8/9
.....
.....


要求一个过程,输出:
姓名 1998年总金额 1999年总金额 2000年总金额 2001年总金额 2002年总金额 ......(列出所有年份) 该员工全部金额
张三 110 10 0 200 10 ..... 988
....
....(所有员工信息)


请写出该存储过程(不能建立临时表或表变量)


...全文
154 点赞 收藏 6
写回复
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lynxma 2007-12-24
--建立数据
create table T_money
(
姓名 nvarchar(10),
金额 decimal(18,2),
日期 datetime
)
insert T_money (姓名,金额,日期)
select '张三',100,'1998/4/8' union all
select '张三',10,'1998/7/4' union all
select '李四',20.5,'1999/8/9' union all
select '张三',10,'1999/8/7' union all
select '王五',30.5,'1998/1/1' union all
select '刘二',22.5,'2000/8/4' union all
select '李四',30,'2001/8/9' union all
select '赵一',2,'2002/8/4' union all
select '王五',14,'2000/2/21' union all
select '张三',52,'1999/12/9' union all
select '吴六',33,'2005/8/9' union all
select '刘二',20,'2007/8/9'

--建立查询
declare @str1 varchar(4000)
set @str1='select 姓名'
select @str1=@str1+',isnull(sum(case year(日期) when '+cast(年 as varchar(4))+' then 金额 end),0) ['
+cast(年 as varchar(4))+'年总金额]'
from (select distinct year(日期) as 年 from T_money) as a
select @str1=@str1+' from T_money group by 姓名'
exec(@str1)

--删除数据
drop table T_money
回复
jxwangjm 2007-12-19
因为年份是1998-2007,是固定的,所以其实极其简单
select t1998.[name],t1998.c1998,1999.c1999
from
(select [name],sum(金额) as c1998
from table1 where left(日期,4)=1998
group by [name]) t1998
full join
(select [name],sum(金额) as c1999
from table1 where left(日期,4)=1999
group by [name]) t1999 on t1998.[name]=t1999.[name]
如果不是固定的年份,则要用多条语句处理
回复
yelloworange 2007-12-13
declare @y bigint
declare @yy varchar(4)
declare @s varchar(200)
declare @ss varchar(3000)
declare @sss varchar(8000)
select @y=min(datepart(yy,[date])) from tt
select @s=''
select @ss=''
select @sss=''
while(@y <=datepart(yy,getdate()))
begin
select @yy=cast(@y as char(4))
/*select @yy*/
select @s='sum(case when datepart(yy,[date])='+@yy+' then total else 0 end) as '''+@yy+ '总金额'',' from tt group by name,datepart(yy,[date])
select @y=@y+1
select @ss=@ss+@s
select @sss='select name,'+left(ltrim(@ss),len(ltrim(@ss))-1)+' from tt group by name'

end
print @sss

执行@sss字符串可得出表
回复
yelloworange 2007-12-13
declare @y bigint
declare @yy varchar(4)
declare @s varchar(200)
declare @ss varchar(8000)
select @y=min(datepart(yy,[date])) from tt
select @s=''
select @ss=''
while(@y <=datepart(yy,getdate()))
begin
select @yy=cast(@y as char(4))
/*select @yy*/
select @s='sum(case when datepart(yy,[date])='+@yy+' then total else 0 end) as '''+@yy+ '总金额'',' from tt group by name,datepart(yy,[date])
select @y=@y+1
select @ss=@ss+@s

end
@ss可得出动态的列名以及对应值
回复
yowbell 2007-12-12
分少点儿~~
回复
fcuandy 2007-12-12
标准的动态行转列.
取得group聚合值后再转.

一搜一堆.
我不nb,写不出来,也没打算去,呵呵.
回复
发动态
发帖子
MS-SQL Server
创建于2007-09-28

3.2w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
社区公告
暂无公告