sql列转行2007-01-15 10:12<br>CREATE TABLE [Test] (<br>[id] [int] IDENTITY (1, 1) NOT NULL ,<br>[name] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,<br>[subject] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,<br>[Source] [numeric](18, 0) NULL <br>) ON [PRIMARY]<br>GO<br><br>INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'数学',75)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'语文',57)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'英语',100)<br>Go<br><br>--交叉表语句的实现:<br>--用于:交叉表的列数是确定的<br>select name,sum(case subject when '数学' then source else 0 end) as '数学',<br>sum(case subject when '英语' then source else 0 end) as '英语',<br>sum(case subject when '语文' then source else 0 end) as '语文' <br>from test <br>group by name<br><br>--用于:交叉表的列数是不确定的<br>declare @sql varchar(8000)<br><br>set @sql = 'select name,'<br>select @sql = @sql + 'sum(case subject when '''+subject+''' <br>then source else 0 end) as '''+subject+''','<br>from (select distinct subject from test) as a <br>select @sql = left(@sql,len(@sql)-1) + ' from test group by name'<br>exec(@sql)<br>go<br><br><br>一个列转行的SQL(竖表变成横表)<br>2008-03-19 19:20<br><br>CREATE TABLE [dbo].[student](<br>[name] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,<br>[kecheng] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,<br>[chengji] [int] NULL<br>) ON [PRIMARY]<br>表结构:<br>name kecheng chengji <br>张三 语文 78<br>李斯 语文 89 <br>张三 数学 78<br>李斯 数学 89 <br>-----------------------------------------------------------------------------------------------------<br><br>declare cur cursor for select distinct kecheng from student<br>declare @kechengforcur varchar(50)<br>declare @strsql varchar(2000)<br>set @strsql='select name '<br>open cur<br>fetch from cur into @kechengforcur <br>while @@fetch_status=0<br>begin <br> set @strsql=@strsql+', sum(case kecheng when '''+@kechengforcur+''' then chengji end)as '+ @kechengforcur <br>-- set @strsql=@strsql+', sum(case kecheng when '''+@kechengforcur+''' then chengji else 0 end)as '+ @kechengforcur <br> fetch from cur into @kechengforcur <br>end<br>set @strsql=@strsql+', round(avg(chengji+0.0),2)as 平均分,sum(chengji)as 总分'<br>set @strsql=@strsql+' from student group by name'<br>close cur<br>DEALLOCATE cur<br>print @strsql<br>exec(@strsql)<br>结果:<br>name 语文 数学 平均分 总分<br>张三 78 78 78 156<br>李斯 89 89 89 178 <br><br>sql server行转列 - 列转行--交叉表实现<br>2007/11/21 19:38<br>主要应用case语句来解决行转列的问题 <br>行转列问题主要分为两类<br>1)简单的行转列问题:<br>示例表:<br>id sid course result<br>1 2005001 语文 80.0<br>2 2005001 数学 90.0<br>3 2005001 英语 80.0<br>4 2005002 语文 56.0<br>5 2005002 数学 69.0<br>6 2005002 英语 89.0<br>执行<br>select sid,语文=isnull(sum(case course when '语文' then result end),0),<br> 数学=isnull(sum(case course when '数学' then result end),0),<br> 英语=isnull(sum(case course when '英语' then result end),0)<br> from result <br> group by sid<br> order by sid<br>得出结果<br>sid 语文 数学 英语<br>2005001 80.0 90.0 80.0<br>2005002 56.0 69.0 89.0<br>2)较为复杂的行转列<br>表1:course<br>id name<br>1 语文<br>2 数学<br>3 英语<br><br>表2:result<br>id sid course result<br>1 2005001 语文 80.0<br>2 2005001 数学 90.0<br>3 2005001 英语 80.0<br>4 2005002 语文 56.0<br>5 2005002 数学 69.0<br>6 2005002 英语 89.0<br>declare @sql varchar(8000)<br>set @sql='select sid'<br>select @sql=@sql+','+course.name+'=isnull(sum(case course when '''+course.name+''' then result end),0)'<br>from course order by id <br>set @sql=@sql+' from result group by sid order by sid'<br>print @sql<br>exec(@sql)<br>得出结果<br>sid 语文 数学 英语<br>2005001 80.0 90.0 80.0<br>2005002 56.0 69.0 89.0<br>-----------------列转行---------------------------------------------------------------------------------------------------------<br>有字符串'1,2,3,4,5,,6,7,8,'这样的不定长字符串,要求将其转成一列N行来存储,也就是列转行,哪种方式最快.<br>经过讨论,下列方式最快.<br>declare @var varchar(8000)<br> ,@sql varchar(8000)<br> ,@last varchar(1)<br> ,@ctrl int<br>set @var='1,2,3,4,5,,6,7,'<br>set @ctrl=0<br>while @ctrl=0<br>begin<br>if (select charindex(',,',@var))>0<br> select @var=replace(@var,',,',',')<br>else<br> set @ctrl=1 <br>end<br>set @last=right(@var,1)<br>if @last=','<br>set @var=left(@var,len(@var)-1)<br>set @sql='select '+replace(@var,',',' union all select '<br>-------------------------------------------------可运行的------------------------------------<br>--交叉表语句的实现:<br>CREATE TABLE Test<br>(<br>id int IDENTITY(1,1) NOT NULL,<br>name nvarchar(50) NULL,<br>subject nvarchar(50) NULL,<br>Source numeric(18,0) NULL<br>)<br>GO<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'数学',75)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'语文',57)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)<br>INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'英语',100)<br>Go<br>SELECT * FROM TEST<br>--用于:交叉表的列数是确定的<br>select name,sum(case subject when '数学' then source else 0 end) as '数学',<br>sum(case subject when '英语' then source else 0 end) as '英语',<br>sum(case subject when '语文' then source else 0 end) as '语文'<br>from test<br>group by name<br>--用于:交叉表的列数是不确定的<br>declare @sql varchar(8000)<br>set @sql = 'select name'<br>select @sql = @sql + ',sum(case subject when '''+subject+'''<br> then source else 0 end) as '''+subject+''' '<br>from (select distinct subject from test) as a<br>select @sql = @sql + ' from test group by name'<br>exec(@sql)