行列转换问题,分不成问题

blueshu 2003-05-07 11:21:38
我有一表table1,其字段数不定

a b c d e f g ....此行为列
1 2 3 4 5 6 7 .... 数据
7 6 3 4 5 6 7 .... 数据
现我要把table1生成为如下的表table2,f1,f2,f3,f4为tabl2的字段,字段数固定
f1为table1的行号,用来标识是哪一行的数据
f1 f2 f3 f4
1 a 1
1 b 2
1 c 3
......
2 a 7
2 b 6
......
请问上述功能用存储过程的较好的算法是什么?
请写个example
谢了先
...全文
13 点赞 收藏 9
写回复
9 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zhxiuli 2003-07-10
收藏
回复
create table #t1 (f1 int,f2 varchar(100),f3 varchar(100),f4 varchar(100))
select *, identity(int,1,1) as tid into #t from table1
declare @colname varchar(300)
declare @colid int
set @colid = 0
while exists (select * from syscolumns A left join sysobjects B on A.id = B.id
where B.name = 'table1' and A.colid > @colid)
begin
select top 1 @colname = A.name, @colid = A.colid from syscolumns A left join
sysobjects B on A.id = B.id where B.name = 'table1' and A.colid > @colid
exec ("insert #t1 select tid, '"+@colname+"', cast("+@colname+" as varchar) ,null from #t")
end

select * from #t1 order by f1
回复
happydreamer 2003-05-07
转贴

create proc up_transpose_table (@tablename nvarchar(256))
as
begin
set nocount on
declare @col nvarchar(256)
declare @makesql nvarchar(4000)
declare @insertsql nvarchar(4000)
declare @caculatesql nvarchar(400)
declare @count int
declare @i int
create table #tmp (colname nvarchar(20))
select @caculatesql = 'select @count=count(1) from ' + @tablename
exec sp_executesql @caculatesql, N'@count int output',@count output
if @count >=1024
begin
raiserror('too many rows, could not be transposed!',16,1)
end
else
begin
select @i=0
while @count >0
begin
select @i=@i+1
select @makesql = 'alter table #tmp add col'+convert(varchar(20),@i)+' int'
exec(@makesql)
select @count=@count-1
end
declare my_cursor cursor for
select name from syscolumns where id=object_id(@tablename) order by colid
open my_cursor
fetch next from my_cursor into @col
while @@fetch_status = 0
begin
select @makesql ='select @insertsql= @insertsql + convert(varchar(4),'+@col+') +'','' from ' +@tablename
select @insertsql =N'insert #tmp values ('''+@col+ ''','
execute sp_executesql @makesql,N'@insertsql nvarchar(4000) output' ,@insertsql output
select @insertsql = left(@insertsql,len(@insertsql)-1) +')'
exec(@insertsql)
fetch next from my_cursor into @col
end
close my_cursor
deallocate my_cursor
select * from #tmp
set nocount off
end
end

回复
大健 2003-05-07
找不到连接了,整编贴出来:





主  题: MSSQL中,有位网友email问我的问题,下面是我给出的方案,大家也来看一看吧.(zhuzhichao)
作  者: zhuzhichao (竹之草)
等  级:
信 誉 值: 100
所属论坛: MS-SQL Server 基础类
问题点数: 300
回复次数: 60
发表时间: 2002-1-30 10:03:24




问题描述:
有表Table2,其结构及内容如下:
Table2:

id name1 name2 name3 ……(列有很多)
1 aa bb cc ……
2 ii jj kk ……
3 xx yy zz ……
…………………………………………

有表Table1,其结构如下:
Table1:
id variable

现在想把Table2中的除id以外的字段名(注意,是字段名)填入Table1中的id,
从Table2中提取某一行(先假设是id为1的那一行吧)中与每个字段名对应的内容填入Table1的variable.

以id为1的那行为例,就是要达到如下的效果:
Table1:
id variable
name1 aa
name2 bb
name3 cc
……………….


我的解决方案:

declare @vVariable varchar(2000),@var varchar(2000) --中間值的變量
declare @sql nvarchar(4000) -- 動態sql
declare @insertSql varchar(4000) -- 插入臨時表的sql
set @vVariable = ' '
if object_id('tempdb.dbo.#temp1') is not null
drop table #temp1
select identity(int) id,name into #temp1 from syscolumns where id = object_id('Table2') and name <> 'id' order by colid

if object_id('tempdb.dbo.#temp2') is null -- 創建臨時表#temp2
create table #temp2
(
id int identity,
variable varchar(10)
)
else
truncate table #temp2

select @vVariable = @vVariable + '+'',''+' + name from syscolumns where id =
object_id('Table2') and name <> 'id' order by colid
set @vVariable = right(@vVariable,len(@vVariable) - 6)
set @sql = 'select @var = '+@vVariable+' from Table2 where id = 1'
exec sp_executesql @sql,N'@var varchar(2000) output',@var output -- 組成以逗號分格的變量@var

set @insertSql='insert into #temp2 values('''+REPLACE(@var,',',''')
insert into #temp2 values(''')+''')'
exec (@insertSql) -- 根據變量中的逗號分格插入臨時表

insert into Table1(id,variable)
select name,variable from #temp1,#temp2
where #temp1.id = #temp2.id

select * from Table1






回复人: kakua(青松客) ( ) 信誉:100 2002-1-30 10:19:35 得分:6



很好





Top

回复人: kakua(青松客) ( ) 信誉:100 2002-1-30 10:26:27 得分:6



很好





Top

回复人: LiaoCheng(光辉岁月) ( ) 信誉:100 2002-1-30 10:32:28 得分:6



收藏!!!
如果反过来又怎么实现呢 .....思考中.....





Top

回复人: kakua(青松客) ( ) 信誉:100 2002-1-30 10:32:40 得分:6



这里也太慢了,可否将论坛改一种格式,加快速度,不然老半天也出不来。





Top

回复人: progame(这个年轻人虽然资历低,但是...) ( ) 信誉:100 2002-1-30 10:39:18 得分:6



竹兄:

就是利用你出的趣味SQL问题上的方法可以实现

而且




Top

回复人: progame(这个年轻人虽然资历低,但是...) ( ) 信誉:100 2002-1-30 10:40:00 得分:6



竹兄:

就是利用你出的趣味SQL问题上的方法可以实现

而且你用的也是这个方法:)




Top

回复人: zhuzhichao(竹之草) ( ) 信誉:100 2002-1-30 10:55:09 得分:0



不錯,這里也用到了那樣的技巧.
不過,這段程序的技巧更多.
如能將每個步驟搞清的話,將對你很有幫助.

LiaoCheng(Flower_梦里看花!!):
如果要反過來,請看
http://www.itpub.net/showthread.php?s=&threadid=11308
有很詳細的說明.






Top

回复人: net_steven(吃素的狼(平平淡淡)) ( ) 信誉:100 2002-1-30 11:00:38 得分:6



生成pivot table的问题,论坛里总有人问。
竹兄这个是地道的解决办法,谢了,收藏。不过建议针对所有记录应该再
把循环处理的语句加进去,再写一个由table1生成table2的过程(改用table变量写吧,大家多一点学习内容)。这样如再有类似提问,用此贴就可以解决了。




Top

回复人: net_steven(吃素的狼(平平淡淡)) ( ) 信誉:100 2002-1-30 11:08:00 得分:6



生成pivot table的问题,论坛里总有人问。
竹兄这个是地道的解决办法,谢了,收藏。不过建议针对所有记录应该再
把循环处理的语句加进去,再写一个由table1生成table2的过程(改用table变量写吧,大家多一点学习内容)。这样如再有类似提问,用此贴就可以解决了。




Top

回复人: Haiwer(海阔天空) ( ) 信誉:100 2002-1-30 14:13:42 得分:6



斑竹,干脆把如下格式的也写了:

Table1:
id var1 var2 var3 ..... (这里的1,2,3.....是ID的值)
name1 aa ii xx ……
name2 bb jj yy ……
name3 cc kk zz ……
……………….








Top

回复人: zhuzhichao(竹之草) ( ) 信誉:100 2002-1-30 14:50:16 得分:0



to Haiwer(海阔天空):

好,马上就写.





Top

回复人: zhuzhichao(竹之草) ( ) 信誉:100 2002-1-30 15:13:39 得分:0



按照Haiwer(海阔天空)的格式也寫好了.


declare @vVariable varchar(2000),@var varchar(2000) --中間值的變量
declare @sql nvarchar(4000) -- 動態sql
declare @insertSql varchar(4000) -- 插入臨時表的sql
declare @alterSql varchar(100) -- 修改臨時表#temp1的sql
declare @updateSql varchar(200) -- 更新臨時表#temp1的數據sql
declare @i int,@count int -- Table2的紀錄數
select @count = count(1) from Table2;
if @count = 0
begin
print 'No row'
return
end
if @count > 254
begin
print 'Too many rows'
return
end
set @vVariable = ' '
select @vVariable = @vVariable + '+'',''+' + name from syscolumns where id =
object_id('Table2') and name <> 'id' order by colid
set @vVariable = right(@vVariable,len(@vVariable) - 6)

if object_id('tempdb.dbo.#temp1') is not null
drop table #temp1
select identity(int) id,name into #temp1 from syscolumns where id = object_id('Table2') and name <> 'id' order by colid

set @i = 1
while (@i <= @count)
begin
if object_id('tempdb.dbo.#temp2') is null -- 創建臨時表#temp2
create table #temp2
(
id int identity,
variable varchar(10)
)
else
truncate table #temp2

set @sql = 'select @var = '+@vVariable+' from Table2 where id = ' + convert(varchar(3),@i)
exec sp_executesql @sql,N'@var varchar(2000) output',@var output -- 組成以逗號分格的變量@var

set @insertSql='insert into #temp2 values('''+REPLACE(@var,',',''')
insert into #temp2 values(''')+''')'
exec (@insertSql) -- 根據變量中的逗號分格插入臨時表

set @alterSql = 'alter table #temp1 add var' + convert(varchar(3),@i) + ' varchar(10)'
exec (@alterSql) -- 增加臨時表的字段

set @updateSql = 'update #temp1 set var' + convert(varchar(3),@i) + ' = variable from #temp2 '
+'where #temp1.id = #temp2.id'
exec (@updateSql) -- 更新臨時表的數據

set @i = @i + 1
end
alter table #temp1 drop column id
select * from #temp1
回复
CrazyFor 2003-05-07
用游标做吧.
回复
myxchy 2003-05-07
t1的行和t2的f1,f2,f3,f4如何对应,有条件吗?
回复
zhoufenghubei 2003-05-07
去sqlsever论坛中找找,有现成的例子!
回复
yoki 2003-05-07
declare @sql varchar(8000)
select identity(int,1,1) row,* into #temp from table1
declare xcursor cursor for select name from syscolumns where id=object_id('table1')
declare @name varchar(20)
open xcursor
fetch xcursor into @name
while @@fetch_status=0
begin
set @sql= 'insert into table2(f1,f2,f3) select a.row,'''+ @name + ''',a.'+@name+' from #temp a,syscolumns b where b.id=object_id(''table1'') and b.name='''+@name+''''
exec (@sql)
fetch xcursor into @name
end
close xcursor
deallocate xcursor
drop table #temp
回复
yoki 2003-05-07
create table table1(aa int, b int, c int, d int, e int,f int, g int)
insert into table1 values(111, 2, 3, 4, 5, 6, 7 )
insert into table1 values(7, 6 , 3 , 4 , 5 ,6 , 7 )

create table table2 (f1 int,f2 varchar(20),f3 int,f4 int)

declare @sql varchar(8000)
select identity(int,1,1) row,* into #temp from table1
declare xcursor cursor for select name from syscolumns where id=object_id('table1')
declare @name varchar(20)
open xcursor
fetch xcursor into @name

while @@fetch_status=0
begin
set @sql= 'insert into table2(f1,f2,f3) select a.row,'''+ @name + ''',a.'+@name+' from #temp a,syscolumns b where b.id=object_id(''table1'') and b.name='''+@name+''''
exec (@sql)
--select @name
fetch xcursor into @name
end
close xcursor
deallocate xcursor
select * from table2 order by f1
drop table #temp
drop table table1,table2
回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2003-05-07 11:21
社区公告
暂无公告