SQL Server中行列转换 Pivot UnPivot

本文转自:张志涛

原文地址:

http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html

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

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

完整语法:

table_source

PIVOT(

聚合函数(value_column)

FOR pivot_column

IN(<column_list>)

)

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

完整语法:

table_source

UNPIVOT(

value_column

FOR pivot_column

IN(<column_list>)

)

注意:PIVOT、UNPIVOT是SQL Server 2005
的语法,使用需修改数据库兼容级别

 在数据库属性->选项->兼容级别改为   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、使用SQL Server 2000静态SQL

--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、使用SQL Server 2000动态SQL

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

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

declare@sqlvarchar(500)

set@sql='select姓名'

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

from(selectdistinct课程fromtb)a--同from
tb group by课程,默认按课程名排序

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

exec(@sql)

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

declare@sqlvarchar(8000)

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

from(selectdistinct课程fromtb)asa

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

exec(@sql)

姓名       数学        物理        语文

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

李四        84          94          74

张三        83          93          74

4、使用SQL Server 2005静态SQL

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

5、使用SQL Server 2005动态SQL

--使用stuff()

declare@sqlvarchar(8000)

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

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

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

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

exec(@sql)

--或使用isnull()

declare@sqlvarchar(8000)

–-获得课程集合

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

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

exec(@sql)

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

1、使用SQL Server 2000静态SQL

--SQL SERVER 2000静态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、使用SQL Server 2000动态SQL

--SQL SERVER 2000动态SQL

declare@sqlvarchar(500)

set@sql='select姓名'

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

from(selectdistinct课程fromtb)a

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

exec(@sql)

3、使用SQL Server 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 Server 2005动态SQL

--使用stuff()

--

declare@sqlvarchar(8000)

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

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

--同select @sql = @sql + ','+课程from
(select distinct课程from tb)a

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

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

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

(select姓名,sum(分数)总分,
cast(avg(分数*1.0) as decimal(18,2))平均分from
tb group by姓名) n

where m.姓名= n.姓名'

exec(@sql)

--或使用isnull()

declare@sqlvarchar(8000)

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

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

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

@sql+')) b) m ,

(select姓名,sum(分数)总分,
cast(avg(分数*1.0) as decimal(18,2))平均分from
tb group by姓名) n

where m.姓名= n.姓名'

exec(@sql)

二、列转行

1、建立表格

ifobject_id('tb')isnotnulldroptabletb

go

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

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

insertintotbvalues('李四',74,84,94)

go

select*fromtb

go

姓名       语文        数学        物理

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

张三       74          83          93

李四        74          84          94

2、使用SQL Server 2000静态SQL

--SQL SERVER 2000静态SQL。

select*from

(

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

unionall

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

unionall

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

) t

end

姓名       课程 分数

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

李四       语文 74

李四       数学 84

李四       物理 94

张三       语文 74

张三       数学 83

张三       物理 93

2、使用SQL Server 2000动态SQL

--SQL SERVER 2000动态SQL。

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

declare@sqlvarchar(8000)

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

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

fromsyscolumns

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

orderbycolid

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

go

3、使用SQL Server 2005静态SQL

--SQL SERVER 2005动态SQL

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

4、使用SQL Server 2005动态SQL

--SQL SERVER 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://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html

sql server 行转列 Pivot UnPivot的更多相关文章

  1. sql的行转列(PIVOT)与列转行(UNPIVOT) webapi 跨域问题 Dapper 链式查询 扩展 T4 代码生成 Demo (抽奖程序)

    sql的行转列(PIVOT)与列转行(UNPIVOT)   在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比 ...

  2. SQL Server中行列转换 Pivot UnPivot

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  3. sql server 行转列(转载)

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  4. sql的行转列(PIVOT)与列转行(UNPIVOT)

    在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比较快速实现行转列,列转行,而且可扩展性强 一.行转列 1.测 ...

  5. Sql Server 行转列

    --摘自百度 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (… ...

  6. SQL Server 行转列重温

    转载自http://www.cnblogs.com/kerrycode/ 行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER ...

  7. 【转载】SQL Server行转列,列转行

    行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...

  8. SQL Server 行转列,列转行。多行转成一列

    一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...

  9. SQL Server 行转列,列转行

    一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...

随机推荐

  1. button的action属性如果有参数,必须加“:”

    比如: [bt addTarget:self action:@selector(shareButtonClickHandler:) …… 后面未写完 一开始我没加,就报错.

  2. rebot framework的搭建 在windows下

    Robot Framework 介绍 Robot Framework 是一款基于 Python 的功能自动化测试框架.它具备良好的可扩展性,支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进 ...

  3. kill -0

    http://unix.stackexchange.com/questions/169898/what-does-kill-0-do 检查有没有权限杀他

  4. spice up your desktop

    https://wiki.gnome.org/Projects/GnomeShell/CheatSheet windows10用了一段时间,回来看着gnome3-shell是那么的恶心,翻来翻去重新整 ...

  5. idea 端口占用

    netstat -anp | grep 8080 lsof -i:8080 查看8080端口被什么进程占用 kill (-s 9) 12903 -s 9 强制 尽快 12903 上面查出的 PID 其 ...

  6. eclipse 终极操作技巧

    eclipse作为一个java开发必备软件,从用户体验来说,还是蛮一般的(按照初始设置的话),所以有必要进行一些设置上的改良,加上对一些好用的快捷键的挖掘,能让你用eclipse更加得心应手,事半功倍 ...

  7. IOS NSArray 倒序

    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"1",@"2",@"3" ...

  8. php中获取各种路径

    echo $_SERVER['DOCUMENT_ROOT'].""; //获得服务器文档根 echo $_SERVER['PHP_SELF'].""; //获得 ...

  9. UIImagePickerController 相关

    UIImagePickerController是系统封装好的一个导航视图控制器,使用其开发者可以十分方便的进行相机相册相关功能的调用.UIImagePickerController继承于UINavig ...

  10. makefile中使用echo向文件中输出版本号和编译时间

    @echo "#define BUILD_TIME" `date +"%F_%H:%M:%S"` > buildTime_svnVer.h @echo & ...