高难度SQL问题,挑战SQL高手!!(300分重谢)(300分)

  • 主题发起人 m_phoenix
  • 开始时间
M

m_phoenix

Unregistered / Unconfirmed
GUEST, unregistred user!
TABLE1:
字段:
a b c d e f g h
数据:
A1 1 2 3 4 5 6 7
A2 23 15 55 22 3 54 5
A3 15 5 58 65 4 4 4
...
An 12 12 15 58 48 88 6
问:怎样才能把TABLE1转换成TABLE2的格式:
TABLE2:
字段:
FF A1 A2 A3 .. An
数据:
a 1 23 .. 12
b 2 15 12
c 3 15
.. 4
h 7 .. 6
 
是要动态创建表吗?
就是根据有多少个An就创建多少个字段!
如果不是这样的话!恩,我就不说了!
 
TO Dae:
正是这样,有什么好办法?应该怎么做?
 
方法有二
1、做存储过程,动态拼写SQL语句来完成。
2、先转存为Access数据表,利用Access的TRANSFORM命令来完成表的交叉动作。
 
TO:QuickSilver
对于第一种方法,能不能详细说一下,谢谢了
 
参考
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1261656
 
是要建表还是SQL查询出TABLE2的结果????
 
to xiaoywh

查询出结果就可以的了,该怎么做呢?
 
怎么没有人会答呢?
 
兄弟:看看:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1524814
我有详细说明,方法类似
 
TO sunrainwang兄:
能详细说一下吗?
谢谢了
 
在sql server2000下用下面的存储过程可以满足你的需要,更改后可以实现更强的功能,
其中e1是原始表,e2根据e1建立,
[red]declare cc cursor scroll for select distinct a from e1[/red]
open cc /*建立游标并打开*/

declare @s char(2),@ss varchar(255)
fetch first from cc into @s
set @ss='create table e2(FF char(2),'
set @ss=@ss+@s+' char(2)'

while @@fetch_status=0
begin
fetch next from cc into @s
if @@fetch_status=0
set @ss=@ss++','+@s+' char(2)'
else
set @ss=@ss+')'
end

if not exists(select * from sysobjects where name='e2' )
exec(@ss) /*执行动态建立的sql语句,建立表e2*/
else begin
print('表已经存在,并将被删除')
drop table e2
exec(@ss)
end

declare @i integer,@cn varchar(127),@cv varchar(127),@tn varchar(127)
set @i=0
set @ss=''

set @cn=(select col_name(object_id('e1'),@i+1))
set @tn=@cn   /*由于你上面所举示例有误,即数据转置后你又增加一个字段,造成字段名和*/
         /*数据相差一行,此处用一临时变量存储以便满足数据的对应关系,*/
set @cn=(select col_name(object_id('e1'),@i+2))
while @cn is not null
begin
if exists(select * from sysobjects where name='tp' )
drop table tp
set @cv='select '+@cn+' into tp from e1'
exec(@cv)
declare tc cursor for select * from tp
open tc /*按临时表建立一个游标,遍历其每一行数据*/

set @ss='insert e2 values('+ ''''+@tn+''','
fetch next from tc into @cv
set @ss=@ss+''''+@cv+''''

while @@fetch_status=0
begin
fetch next from tc into @cv
if @@fetch_status=0
set @ss=@ss+','+ ''''+@cv+''''
else
set @ss=@ss+')'
end

exec(@ss) /*在e2中插入数据*/

close tc
deallocate tc
/*关闭并删除临时游标*/
set @i=@i+1
set @tn=@cn
set @cn=(select col_name(object_id('e1'),@i+2))
end

要验证以上sql语句,可以在库中建立一个表e1,其第一个字段为a就可以了(这是上面红字那行的限制,不过可以
更改一下使它通用,我没有时间了就没有改),然后在sql查询分析器中执行就可以得到一个表e2,可以查看此表中的
数据是否正确。
另外要想实现更高级的功能,可以将以上程序改为一个用户自定义函数,使它返回一个行集,这样
就可以直接用select语句返回想要的结果了。
 
谢谢:windbell
明天过来结贴
 
不好意思,才上来,好象已经解决了。
不过看到sunrainwang,的这个帖子
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1524814
感觉在oracle中很经典。
 
在上面的过程中,最外层的游标在任务完成后忘记删除了,最后要加上
close cc
deallocate cc
另外上面的过程中由于增加了注释,所以在语句中语法有的地方可能能不过,现在更改如下,这
样可以直接拷贝执行了:
declare cc cursor scroll for select distinct a from e1
open cc

/*建立游标并打开*/

declare @s char(2),@ss varchar(255)
fetch first from cc into @s
set @ss='create table e2(FF char(2),'
set @ss=@ss+@s+' char(2)'

while @@fetch_status=0
begin
fetch next from cc into @s
if @@fetch_status=0
set @ss=@ss +','+@s+' char(2)'
else
set @ss=@ss+')'
end

if not exists(select * from sysobjects where name='e2' )
exec(@ss)

/*执行动态建立的sql语句,建立表e2*/

else begin
print('表已经存在,并将被删除')
drop table e2
exec(@ss)
end

declare @i integer,@cn varchar(127),@cv varchar(127),@tn varchar(127)
set @i=0
set @ss=''

set @cn=(select col_name(object_id('e1'),@i+1))
set @tn=@cn

/*由于你上面所举示例有误,即数据转置后你又增加一个字段,造成字段名和
数据相差一行,此处用一临时变量存储以便满足数据的对应关系,*/

set @cn=(select col_name(object_id('e1'),@i+2))
while @cn is not null
begin
if exists(select * from sysobjects where name='tp' )
drop table tp
set @cv='select '+@cn+' into tp from e1'
exec(@cv)
declare tc cursor for select * from tp
open tc

/*按临时表建立一个游标,遍历其每一行数据*/

set @ss='insert e2 values('+ ''''+@tn+''','
fetch next from tc into @cv
set @ss=@ss+''''+@cv+''''

while @@fetch_status=0
begin
fetch next from tc into @cv
if @@fetch_status=0
set @ss=@ss+','+ ''''+@cv+''''
else
set @ss=@ss+')'
end

exec(@ss)

/*在e2中插入数据*/

close tc
deallocate tc
/*关闭并删除临时游标*/
set @i=@i+1
set @tn=@cn
set @cn=(select col_name(object_id('e1'),@i+2))
end
close cc
deallocate cc
还必须要说明的是在表e1中在第一个字段即a中不能有重复值,最好该字段为主关键字段
 
这个是经典:
http://expert.csdn.net/Expert/topic/508/508081.xml?temp=.2444879
 
多人接受答案了。
 
顶部