首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

高分请问,SQL数值转换

2012-01-14 
高分请教,SQL数值转换表A中的一部分:姓名年1月2月3月4月5月6月7月8月9月……12月--------------------------

高分请教,SQL数值转换
表A中的一部分:
姓名         年         1月     2月     3月     4月     5月     6月     7月     8月     9月……12月
------------------------------
张三         2006     0         0         0         0         0         0         11       0         0     ……15
张三         2007     50       20       30       0         16       0         0         0         0     ……0


最后需要的的结果为:
姓名       帐期
--------------------------------
张三       06.7/12/07.1-3/5


我的思路步骤是:
第一步:如果数值大于0,则将该月份记录下来:
                        2006年中大于0的月份有:7、12
                        2007年中大于0的月份有:1、2、3、5
第二步:逐个对比月份数,如果月份相连续的,则用减号“-”将其连起来;如果不连续的,则用斜杠“/”分开,并在最前面加上年份。
                        上例2006年的结果为:06.7/12
                        上例2007年的结果为:07.1-3/5
第三步:将姓名相同的结果集用斜杠“/”合并起来,,于是便成了:06.7/12/07.1-3/5。


在高级语言C#里面很容易实现,但是公司要求尽量在数据库中实现,请问我该如何处理呢,我对SQL的知识还不能处理这个问题,拜托大家了。

[解决办法]
--建立环境

create table TbA (
姓名 nvarchar(20),
年 varchar(10),
[1月] int,
[2月] int,
[3月] int,
[4月] int,
[5月] int,
[6月] int,
[7月] int,
[8月] int,
[9月] int,
[10月] int,
[11月] int,
[12月] int
)

go

insert TbA select
------------------------------
N '张三 ', '2006 ', 0, 0, 0, 0, 0, 0, 11, 0, 0,0,0, 15
union all select
N '张三 ', '2007 ', 50, 20, 30, 0 , 16, 0 , 0 , 0 , 0 ,0,0,0
union all select
N '李四 ', '2006 ', 0, 1, 2, 3, 4, 0, 5, 6, 0,7,0,8
union all select
N '李四 ', '2007 ', 9, 10, 0, 11 , 12, 0 , 13 , 0 , 14 ,15,16,0
union all select
N '王五 ', '2007 ', 1, 2, 3, 4 , 5, 6 , 7 , 8 , 9 ,10,11,12


go

--建立函数
create function fn_帐期 (
@姓名 nvarchar(20)
)
returns varchar(400)
as
begin
declare @r varchar(400)

declare @t table (
年 varchar(10),
value int
)
insert @t
select 年,1 from TbA where [1月]> 0 and 姓名=@姓名
union all
select 年,2 from TbA where [2月]> 0 and 姓名=@姓名
union all
select 年,3 from TbA where [3月]> 0 and 姓名=@姓名
union all
select 年,4 from TbA where [4月]> 0 and 姓名=@姓名
union all
select 年,5 from TbA where [5月]> 0 and 姓名=@姓名
union all
select 年,6 from TbA where [6月]> 0 and 姓名=@姓名
union all
select 年,7 from TbA where [7月]> 0 and 姓名=@姓名
union all
select 年,8 from TbA where [8月]> 0 and 姓名=@姓名
union all
select 年,9 from TbA where [9月]> 0 and 姓名=@姓名
union all
select 年,10 from TbA where [10月]> 0 and 姓名=@姓名
union all


select 年,11 from TbA where [11月]> 0 and 姓名=@姓名
union all
select 年,12 from TbA where [12月]> 0 and 姓名=@姓名

declare @t1 table (
id int IDENTITY(1,1),
年 varchar(10),
value int
)

insert @t1(年,value)
select a.年,a.value
from @t a left join @t b
on a.年=b.年 and a.value=b.value+1
where b.年 is null
order by a.年,a.value

declare @t2 table (
id int IDENTITY(1,1),
年 varchar(10),
value int
)

insert @t2(年,value)
select a.年,a.value
from @t a left join @t b
on a.年=b.年 and a.value=b.value-1
where b.年 is null
order by a.年,a.value

set @r= ' '
declare @年 varchar(10)

select @r=@r+case when @年=a.年 then '/ '+
case when a.value <> b.value then cast(a.value as varchar)+ '- '+cast(b.value as varchar) else cast(a.value as varchar) end
else '/ '+right(a.年,2)+ '. '+
case when a.value <> b.value then cast(a.value as varchar)+ '- '+cast(b.value as varchar) else cast(a.value as varchar) end
end,
@年=a.年
from @t1 a,@t2 b
where a.年=b.年 and a.id=b.id
order by a.id

if @r <> ' '
set @r=stuff(@r,1,1, ' ')

return @r
end
go

--调用
select 姓名,dbo.fn_帐期(姓名) as 帐期
from TbA
group by 姓名
order by 姓名

--结果
姓名 帐期
-------------------- ----------------------------------------------------------------------------------------------------------------
王五 07.1-12
李四 06.2-5/7-8/10/12/07.1-2/4-5/7/9-11
张三 06.7/12/07.1-3/5

(所影响的行数为 3 行)

热点排行