微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQLServer行列转换 Pivot UnPivot

PIVOT用于将列值旋转为列名(即行转列),在sql Server 2000可以用聚合函数配合CASE语句实现

PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )ASP

完整语法:

table_source

PIVOT(

聚合函数value_column

FORpivot_column

IN(<column_list>)

)

 

UNPIVOT用于将列明转为列值(即列转行),在sql Server 2000可以用UNION来实现

完整语法:

table_source

UNPIVOT(

value_column

FORpivot_column

IN(<column_list>)

)

 

注意:PIVOT、UNPIVOT是sql Server2005 的语法,使用需修改数据库兼容级别
 
数据库属性->选项->兼容级别改为  90

 

典型实例

一、行转列

1、建立表格

ifobject_id('tb')isnotnulldroptabletb

go

createtabletb(姓名varchar(10),课程varchar(10),分数int)

insertintotbvalues('张三','语文',74)

insertintotbvalues('张三','数学',83)

insertintotbvalues('张三','物理',93)

insertintotbvalues('李四',74)

insertintotbvalues('李四',84)

insertintotbvalues('李四',94)

go

select*fromtb

go

姓名       课程       分数

---------- ---------------------

张三       语文       74

张三       数学       83

张三       物理       93

李四       语文       74

李四       数学       84

李四       物理       94

 

2、使用sqlServer 2000静态sql

@H_502_804@--c

select姓名,

 max(case课程when'语文'then分数else0end)语文,

 max(case课程when'数学'then分数else0end)数学,

 max(case课程when'物理'then分数else0end)物理

fromtb

groupby姓名

姓名       语文        数学        物理

---------- ---------------------- -----------

李四       74         84         94

张三       74         83         93

 

3、使用sqlServer 2000动态sql

@H_502_804@--sqlSERVER 2000动态@H_502_804@sql,指课程不止语文、数学、物理这三门课程。@H_502_804@(以下同@H_502_804@)

@H_502_804@--变量按@H_502_804@sql语言顺序赋值

declare@sqlvarchar(500)

set@sql='select姓名'

select@sql=@sql+',max(case课程when'''+课程+''' then分数else0 end)['+课程+']'

from(selectdistinct课程fromtb)a--@H_502_804@fromtb group by课程,认按课程名排序

set@sql=@sql+'from tb group by姓名'

exec(@sql)

 

@H_502_804@--使用@H_502_804@isnull(),变量先确定动态部分

declare@sqlvarchar(8000)

select@sql=isnull(@sql+',','')+'max(case课程when'''+课程+'''then分数else0 end) ['+课程+']'

from(selectdistinct课程fromtb)as     

set@sql='select姓名,'+@sql+'from tb group by姓名'

exec(@sql)

姓名       数学        物理        语文

---------- ---------------------- -----------

李四       84         94         74

张三       83         93         74

 

4、使用sqlServer 2005静态sql

select*fromtb pivot(max(分数)for课程in(语文,数学,物理))a

 

5使用sql Server2005动态sql

@H_502_804@--使用@H_502_804@stuff()

declare@sqlvarchar(8000)

set@sql=''  --初始化变量@H_502_804@@sql

select@sql=@sql+','+课程fromtbgroupby课程@H_502_804@--变量多值赋值

set@sql=stuff(@sql,1,'')--去掉首个@H_502_804@','

set@sql='select* from tb pivot(max(分数)for课程in('+@sql+'))a'

exec(@sql)

 

@H_502_804@--或使用@H_502_804@isnull()

declare@sqlvarchar(8000)

@H_502_804@–-获得课程集合

select@sql=isnull(@sql+','')+课程fromtbgroupby课程           

set@sql='select* from tb pivot(max(分数)for课程in('+@sql+'))a'

exec(@sql)

 

二、行转列结果加上总分、平均分

1、使用sqlServer 2000静态sql

@H_502_804@--sqlSERVER 2000静态@H_502_804@sql

select姓名,

max(case课程when'语文'then分数else0end)语文,

max(case课程when'数学'then分数else0end)数学,

max(case课程when'物理'then分数else0end)物理,

sum(分数)总分,

cast(avg(分数*1.0)asdecimal(18,2))平均分

fromtb

groupby姓名

姓名       语文        数学        物理        总分        平均分

---------- ---------------------- ----------- -----------

李四       74         84         94         252        84.00

张三       74         83         93         250        83.33

 

2、使用sqlServer 2000动态sql

@H_502_804@--sqlSERVER 2000动态@H_502_804@sql

declare@sqlvarchar(500)

set@sql='select姓名'

select@sql=@sql+',max(case课程when'''+课程+''' then分数else0 end)['+课程+']'

from(selectdistinct课程fromtb)a

set@sql=@sql+',sum(分数)总分,cast(avg(分数*1.0)as decimal(18,2))     平均分fromtb group by姓名'

exec(@sql)

 

3、使用sqlServer 2005静态sql

selectm.*,n.总分,n.平均分

from

(select*fromtb pivot(max(分数)for课程in(语文,物理))a)m,

(select姓名,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分

fromtb

groupby姓名)n

wherem.姓名=n.姓名

 

4、使用sql Server2005动态sql

@H_502_804@--使用@H_502_804@stuff()

@H_502_804@--

declare@sqlvarchar(8000)

set@sql=''  --初始化变量@H_502_804@@sql

select@sql=@sql+','+课程fromtbgroupby课程@H_502_804@--变量多值赋值

@H_502_804@--@H_502_804@select@sql = @sql + ','+课程@H_502_804@from(select distinct课程@H_502_804@fromtb)a

set@sql=stuff(@sql,'

set@sql='selectm.*,n.总分,n.平均分from

(select *from (select * from tb) a pivot (max(分数)for课程in('+@sql+')) b) m,

(select姓名,sum(分数)总分,2))平均分fromtb group by姓名)n

wherem.姓名=n.姓名'

exec(@sql)

 

@H_502_804@--或使用@H_502_804@isnull()

declare@sqlvarchar(8000)

select@sql=isnull(@sql+','')+课程fromtbgroupby课程

set@sql='selectm.*,n.平均分from

(select *from (select * from tb) a pivot (max(分数)for课程in('+

 @sql+'))b) m,

(select姓名,2))平均分fromtb group by姓名)n

wherem.姓名=n.姓名'

exec(@sql)

 

二、列转行

1、建立表格

ifobject_id('tb')isnotnulldroptabletb

go

createtabletb(姓名varchar(10),语文int,数学int,物理int)

insertintotbvalues('张三',74,83,93)

insertintotbvalues('李四',84,94)

go

select*fromtb

go

姓名       语文        数学        物理

---------- ---------------------- -----------

张三       74         83         93

李四       74         84         94

 

2、使用sqlServer 2000静态sql

--sqlSERVER 2000静态sql

select*from

(

 select姓名,课程='语文',分数=语文fromtb

 unionall

 select姓名,课程='数学',分数=数学fromtb

 unionall

 select姓名,课程='物理',分数=物理fromtb

)t

orderby姓名,case课程when'语文'then1when'数学'then2when'物理'then3end

姓名       课程 分数

---------- ---------------

李四       语文 74

李四       数学 84

李四       物理 94

张三       语文 74

张三       数学 83

张三       物理 93

  

2、使用sqlServer 2000动态sql

--sqlSERVER 2000动态sql

--调用系统表动态生态。

declare@sqlvarchar(8000)

select@sql=isnull(@sql+'union all ','')+'select姓名,[课程]='

+quotename(Name,'''')+',[分数]= '+quotename(Name)+' fromtb'

fromsyscolumns

whereName!='姓名'andID=object_id('tb')--表名@H_502_804@tb,不包含列名为姓名的其他列

orderbycolid

exec(@sql+'order by姓名')

go

 

3、使用sqlServer 2005静态sql

--sqlSERVER 2005动态sql

select姓名,课程,分数fromtbunpivot (分数for课程in([语文],[数学],[物理]))t

 

4、使用sql Server2005动态sql

--sqlSERVER 2005动态sql

declare@sqlnvarchar(4000)

select@sql=isnull(@sql+','')+quotename(Name)

fromsyscolumns

whereID=object_id('tb')andNamenotin('姓名')

orderbyColid

set@sql='select姓名,[课程],[分数]from tb unpivot ([分数]for [课程]in('+@sql+'))b'

exec(@sql)


http://blog.sina.com.cn/s/blog_81b2b2a101010ka2.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐