原文的SQL语句有些小错误,下面的是改正且测试通过的。感谢原文作者 :)
有一个表:
BH GZLB JE
----------------------
001 A 100
001 B 150
001 C 110
002 A 99
002 B 180
002 C 150
003 A 160
003 B 170
003 C 130
用SQL语句如何将上面的表变成下面横向的排列方式呢。
BH A B C
-------------------
001 100 150 110
002 99 180 150
003 160 170 130
(GZLB 里面的字段是动态的,不是只有A,B,C 可能还有A,B,C,D,E...)
先创建以上的测试数据表
if
exists
(
select
name
from
sysobjects
where
name
=
'
tblA
'
and
xtype
=
'
U
'
)
drop table tblA
create table tblA(
BH char ( 3 ) not null ,
GZLB varchar ( 3 ) not null ,
JE int not null
)
go
insert tblA values ( ' 001 ' , ' A ' , 100 )
insert tblA values ( ' 001 ' , ' B ' , 150 )
insert tblA values ( ' 001 ' , ' C ' , 110 )
insert tblA values ( ' 002 ' , ' A ' , 99 )
insert tblA values ( ' 002 ' , ' B ' , 180 )
insert tblA values ( ' 002 ' , ' C ' , 150 )
insert tblA values ( ' 003 ' , ' A ' , 160 )
insert tblA values ( ' 003 ' , ' B ' , 170 )
insert tblA values ( ' 003 ' , ' C ' , 130 )
drop table tblA
create table tblA(
BH char ( 3 ) not null ,
GZLB varchar ( 3 ) not null ,
JE int not null
)
go
insert tblA values ( ' 001 ' , ' A ' , 100 )
insert tblA values ( ' 001 ' , ' B ' , 150 )
insert tblA values ( ' 001 ' , ' C ' , 110 )
insert tblA values ( ' 002 ' , ' A ' , 99 )
insert tblA values ( ' 002 ' , ' B ' , 180 )
insert tblA values ( ' 002 ' , ' C ' , 150 )
insert tblA values ( ' 003 ' , ' A ' , 160 )
insert tblA values ( ' 003 ' , ' B ' , 170 )
insert tblA values ( ' 003 ' , ' C ' , 130 )
以下是两种不同实现方法,一种用游标一种不用。
declare
@sql
varchar
(
6000
)
set @sql = ' select '
select @sql = @sql + ' sum(case GZLB when ''' + GZLB + ''' then JE else null end) [ ' + GZLB + ' ], ' from ( select distinct GZLB as GZLB from tblA) tmp
set @sql = substring ( @sql , 1 , len ( @sql ) - 1 ) + ' from tblA group by BH '
exec ( @sql )
set @sql = ' select '
select @sql = @sql + ' sum(case GZLB when ''' + GZLB + ''' then JE else null end) [ ' + GZLB + ' ], ' from ( select distinct GZLB as GZLB from tblA) tmp
set @sql = substring ( @sql , 1 , len ( @sql ) - 1 ) + ' from tblA group by BH '
exec ( @sql )
执行结果如图:
下面这个是用游标实现:
declare
@sqlstr
varchar
(
2000
)
declare @gzlb varchar ( 3 )
set @sqlstr = ' select bh '
DECLARE @cgzlb CURSOR
SET @cgzlb = CURSOR LOCAL SCROLL FOR
select distinct gzlb from tblA
create table #tmpA
(bh char ( 3 ))
open @cgzlb
fetch next from @cgzlb into @gzlb
WHILE @@FETCH_STATUS = 0
begin
exec ( ' alter table #tmpA add ' + @gzlb + ' int ' )
exec ( ' insert into #tmpA (bh, ' + @gzlb + ' ) select bh,je from tblA where gzlb= ''' + @gzlb + '''' )
select @sqlstr = @sqlstr + ' ,sum(isnull( ' + @gzlb + ' ,0)) as ' + @gzlb
fetch next from @cgzlb into @gzlb
end
close @cgzlb
deallocate @cgzlb
set @sqlstr = @sqlstr + ' from #tmpA group by bh order by bh '
print @sqlstr
execute ( @sqlstr )
drop table #tmpA
declare @gzlb varchar ( 3 )
set @sqlstr = ' select bh '
DECLARE @cgzlb CURSOR
SET @cgzlb = CURSOR LOCAL SCROLL FOR
select distinct gzlb from tblA
create table #tmpA
(bh char ( 3 ))
open @cgzlb
fetch next from @cgzlb into @gzlb
WHILE @@FETCH_STATUS = 0
begin
exec ( ' alter table #tmpA add ' + @gzlb + ' int ' )
exec ( ' insert into #tmpA (bh, ' + @gzlb + ' ) select bh,je from tblA where gzlb= ''' + @gzlb + '''' )
select @sqlstr = @sqlstr + ' ,sum(isnull( ' + @gzlb + ' ,0)) as ' + @gzlb
fetch next from @cgzlb into @gzlb
end
close @cgzlb
deallocate @cgzlb
set @sqlstr = @sqlstr + ' from #tmpA group by bh order by bh '
print @sqlstr
execute ( @sqlstr )
drop table #tmpA
执行结果如图: