行转列再转行,SQL语句快来帮忙!!!

modelbaby5 2012-11-20 06:57:52
表名:tb1
name1 name2 name3 name4 name5
a b c d e
aa bb cc dd ee

表如上
我要实现的是一行SQL语句实现如下内容
1 name1 a aa
2 name2 b bb
3 name3 c cc
4 name4 d dd
5 name5 e ee

这里的表不是确定的,所以列名也不是确定的,这里查询结果的第2列是要查询出tb1表的列名(name1 name2 name3 name4 name5),后面的列要根据数据表的行数对应增加,也就是说查询结果的列数要根据数据表的行数而变化

各位高手快来指点.80分敬上,不够再加!
...全文
274 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
坚_持 2012-11-24
  • 打赏
  • 举报
回复
坚_持 2012-11-24
  • 打赏
  • 举报
回复
老王 2012-11-22
  • 打赏
  • 举报
回复
谁能给个oracle中的写法啊?
开启时代 2012-11-22
  • 打赏
  • 举报
回复
引用 2 楼 modelbaby5 的回复:
1楼很帅,是我要的查询结果。可是能不能做成简易点的代码?这种是不是只能防在存储过程里面使用?
楼主真是个完美主义者,动态执行的脚本 困难。。。
  • 打赏
  • 举报
回复
--行列互转
--摘自中国风博客,引用请标明内容来源
--1、行换列
if object_id('Class') is not  null
    drop table Class
Go
Create table Class(
[Student] nvarchar(2),
[Course] nvarchar(2),
[Score] int)
Insert Class
select N'张三',N'语文',78 union all
select N'张三',N'数学',87 union all
select N'张三',N'英语',82 union all
select N'张三',N'物理',90 union all
select N'李四',N'语文',65 union all
select N'李四',N'数学',77 union all
select N'李四',N'英语',65 union all
select N'李四',N'物理',85 
Go

--2000方法:
--动态:
declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='    
   
    +quotename([Course],'''')+' then [Score] else 0 end)'
from 
    Class group by[Course]
--select @s
exec('select [Student]'+@s+' from Class group by [Student]')
--生成静态:
select 
    [Student],
    [数学]=max(case when [Course]='数学' then [Score] else 0 end),
    [物理]=max(case when [Course]='物理' then [Score] else 0 end),
    [英语]=max(case when [Course]='英语' then [Score] else 0 end),
    [语文]=max(case when [Course]='语文' then [Score] else 0 end) 
from 
    Class 
group by [Student]
GO
--动态:

declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
select @s
exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')

--生成静态:
select * 
from 
    Class 
pivot 
    (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b

--生成格式:
/*
Student 数学         物理         英语         语文
------- ----------- ----------- ----------- -----------
李四     77          85          65          65
张三     87          90          82          78

(2 行受影响)
*/

go
--加上总成绩(学科平均分)

--2000方法:
--动态:

declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+'then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+',[总成绩]=sum([Score])  from Class group by [Student]')--加多一列(学科平均分用avg([Score]))

生成动态:

select 
    [Student],
    [数学]=max(case when [Course]='数学' then [Score] else 0 end),
    [物理]=max(case when [Course]='物理' then [Score] else 0 end),
    [英语]=max(case when [Course]='英语' then [Score] else 0 end),
    [语文]=max(case when [Course]='语文' then [Score] else 0 end),
    [总成绩]=([Score]) --加多一列(学科平均分用avg([Score]))
from 
    Class 
group by [Student]

go

--2005方法:

动态:

declare @s nvarchar(4000)
Select  @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course] 
--isnull(@s+',','') 去掉字符串@s中第一个逗号

exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a 
pivot (max([Score]) for [Course] in('+@s+'))b ')

--生成静态:

select 
    [Student],[数学],[物理],[英语],[语文],[总成绩] 
from 
    (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])
pivot 
    (max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b 

生成格式:

/*
Student 数学         物理         英语         语文         总成绩
------- ----------- ----------- ----------- ----------- -----------
李四     77          85          65          65          292
张三     87          90          82          78          337

(2 行受影响)
*/

go

--2、列转行
 
if not object_id('Class') is null
    drop table Class
Go
Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
Insert Class
select N'李四',77,85,65,65 union all
select N'张三',87,90,82,78
Go

--2000:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all
+',[Score]='+quotename(Name)+' from Class'
from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列
order by Colid
exec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序

生成静态:
select * 
from (select [Student],[Course]='数学',[Score]=[数学] from Class union all 
select [Student],[Course]='物理',[Score]=[物理] from Class union all 
select [Student],[Course]='英语',[Score]=[英语] from Class union all 
select [Student],[Course]='语文',[Score]=[语文] from Class)t 
order by [Student],[Course]

go
--2005:

动态:

declare @s nvarchar(4000)
select @s=isnull(@s+',','')+quotename(Name)
from syscolumns where ID=object_id('Class') and Name not in('Student') 
order by Colid
exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')

go
select 
    Student,[Course],[Score] 
from 
    Class 
unpivot 
    ([Score] for [Course] in([数学],[物理],[英语],[语文]))b
生成格式:
/*
Student Course Score
------- ------- -----------
李四     数学     77
李四     物理     85
李四     英语     65
李四     语文     65
张三     数学     87
张三     物理     90
张三     英语     82
张三     语文     78
*/
ieagle77 2012-11-21
  • 打赏
  • 举报
回复
如果动态效果的话,就只能放在存储过程中了。
modelbaby5 2012-11-21
  • 打赏
  • 举报
回复
1楼很帅,是我要的查询结果。可是能不能做成简易点的代码?这种是不是只能防在存储过程里面使用?
开启时代 2012-11-20
  • 打赏
  • 举报
回复
create table tb1(name1 varchar(10),name2 varchar(10),name3 varchar(10),name4 varchar(10),name5 varchar(10)) insert into tb1 select 'a','b','c','d','e' union all select 'aa','bb','cc','dd','ee' union all select 'aaa','bbb','ccc','ddd','eee' ----测试 declare @columns varchar(max),@i int,@istr varchar(max),@sqlstr varchar(max) set @istr='' set @i=1 while @i<=(select COUNT(1) from tb1) begin set @istr=@istr+','+quotename(@i) set @i=@i+1 end set @istr=STUFF(@istr,1,1,'') set @columns=stuff((select ','+QUOTENAME(name) from sys.columns where object_id=object_id('tb1') for xml path('')),1,1,'') set @sqlstr='select * from (select * from (select *,ROW_NUMBER() over(order by getdate()) rowid from tb1) as a'+ ' unpivot(TT for name in ('+@columns+')) b) as X'+ ' pivot(max(TT) for rowid in ('+@istr+')) as Y' exec(@sqlstr)

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧