日期:2014-05-18  浏览次数:20462 次

这个只用SQL能实现吗
现在表一如下

年级 班数 起始班 班号
初一 3 2
高二文 3 1,3,4
高二理 2 2,5

要生成如下表二:

年级 班
初一 2
初一 3
初一 4
高二文 1
高二文 3
高二文 4
高二理 2
高二理 5

以前我一般在VB里截取一条一条添加的,能编个存储过程实现吗,利用参数进行传递,这样减少对数据库的访问


------解决方案--------------------
SQL code
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([年级] varchar(6),[班数] int,[起始班] int,[班号] varchar(7))
insert [tb]
select '初一',3,2,null union all
select '高二文',3,null,'1,3,4' union all
select '高二理',2,null,'2,5'

create proc sp_test
as
select 年级,班=b.number from [tb] a 
join master..spt_values b on b.type='P' 
and b.number between 起始班 and 起始班+班数-1 and 班号 is null
union all
select 年级,substring(a.班号,b.number,charindex(',',a.班号+',',b.number)-b.number) 
from tb a join master..spt_values b
on b.type='P' and charindex(',',','+a.班号,b.number)=b.number
where 起始班 is null
go

exec sp_test
/*
年级     班
------ -----------
初一     2
初一     3
初一     4
高二文    1
高二文    3
高二文    4
高二理    2
高二理    5

(8 行受影响)
*/

------解决方案--------------------
SQL code

if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([年级] varchar(6),[班数] int,[起始班] int,[班号] varchar(7))
insert [tb]
select '初一',3,2,null union all
select '高二文',3,null,'1,3,4' union all
select '高二理',2,null,'2,5'


select a.年级,case when a.起始班+b.number IS not null then a.起始班+b.number else 
    (select ap.v1 from (select CAST('<root><v>'+replace(班号,',','</v><v>')+'</v></root>' as xml) as vv from (select a.班号) as ttb )tt outer apply(
        select rn=ROW_NUMBER() over(order by getdate()),N.v.value('.','varchar(10)') v1 from tt.vv.nodes('/root/v') N(v)) ap where ap.rn=b.number+1 )
end 
from tb a join master..spt_values b on a.班数> b.number 
where b.type='p'
--这个复杂了。
/*

年级     
------ -----------
初一     2
初一     3
初一     4
高二文    1
高二文    3
高二文    4
高二理    2
高二理    5

*/

------解决方案--------------------
SQL code

--> 测试数据: @T
declare @T table (年级 varchar(6),班数 int,起始班 int,班号 varchar(10))
insert into @T
select '初一',3,2,null union all
select '高二文',3,null,'1,3,4' union all
select '高二理',2,null,'2,5'

select a.年级,b.number from @T a join master..spt_values b 
on b.number between a.起始班 and 起始班+ 班数-1 and b.type='p'
union all
select A.年级, B.班号 from( 
select 年级, 班号 = convert(xml,' <root> <v>' + replace(班号, ',', ' </v> <v>') + ' </v> </root>') from @T 
where 班号 is not null)A 
outer apply(select 班号 = N.v.value('.', 'varchar(100)') from A.班号.nodes('/root/v') N(v) )B 
/*
年级     number
------ -----------
初一     2
初一     3
初一     4
高二文    1
高二文    3
高二文    4
高二理    2
高二理    5
*/