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. LeetCode OJ 83. Remove Duplicates from Sorted List

    Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...

  2. 9.Java主要有那几种文件类型?各自的作用是什么?

    java类源代码.jsp页面.class编译后的类文件.xml一般是配置文件当然也可以用来传数据时候用.properties这也是配置文件.数据文件.  

  3. document.createDocumentFragment 方法

    基本概念 document.createDocumentFragment 方法会创建一个 DocumentFragment 对象,该对象是一个存在于 DOM 树之外的 DOM 节点.它有一个非常有用的 ...

  4. 在Linux下编写php扩展

    以下内容是本人学习过程中的笔记或者心得,如果有什么建议或者意见请在评论中提醒我,谢谢,这篇文章我会定期更新,由浅到深的分享我学PHP扩展历程 或者在学习中有什么问题欢迎交流 1.去PHP官网下载一个源 ...

  5. Inno Setup入门(七)——提供安装语言选项

    Inno Setup安装目录下有一个Languages的文件夹,该文件夹提供了可供使用的语言,通过在脚本中加入[languages]段,可以实现该项功能,实现代码如下: [setup] ;全局设置,本 ...

  6. 删除cygwin

    由于cygwin 学习了linux 的用户所有者的方式,要删除有一定困难. 所以要右击  然后点 获取管理员所有权  几分钟之后  就可以删了

  7. NaN(Not a Number)问题

    Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contai ...

  8. arcconf

    arcconf create 1 logicaldrive max volume 0 31 noprompt 创建 Logical Drive, 这里 0 31 就是之前记录的 Channel, De ...

  9. seo优化 标点符号

    一.顿号“.” 顿号是一个只有在中文中使用的标点符号,这在英文中没有.毕竟该不该在标题中使用顿号呢,建议大家仍是不要使用,或者说在标题中就不要泛起中文的符号最好.不外,顿号可以使用在Descripti ...

  10. 编写Linux/Unix守护进程

    原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开 ...