sqlserver 行列转换
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
orderby姓名,case课程when'语文'then1when'数学'then2when'物理'then3end
姓名 课程 分数
---------- ---- -----------
李四 语文 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)
sqlserver 行列转换的更多相关文章
- sqlserver行列转换
sqlserver行转列 --创建行转列表及插入数据 create table tb_RowConvertToColumn ( username ) null, course ) null, scor ...
- sqlserver行列转换问题(网上搜集)
(列->行) 一.FOR XML PATH 简单介绍 那么还是首先来介绍一下FOR XML PATH ,假设现在有一张兴趣爱好表(hobby)用来存放兴趣爱好,表结构如 ...
- SQLServer行列转换PIVOT函数中聚合函数的使用意义及选择
例子:https://blog.csdn.net/wikey_zhang/article/details/76849826 DECLARE @limitDay INT;SET @limitDay = ...
- [转载]SQL Server行列转换实现
可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P 完整语法: table_source PIVOT( 聚合函数(value_ ...
- 在Sqlserver下巧用行列转换日期的数据统计
在Sqlserver下巧用行列转换日期的数据统计 前言 在SQLSERVER 中有很多统计函数的基础语法,有使用Group By 或 partition by 后配合Sum,Count(*) 等用法. ...
- sqlserver表分区与调优与行列转换
转自: http://www.cnblogs.com/knowledgesea/p/3696912.html http://www.open-open.com/lib/view/open1418462 ...
- SQL 行列转换简单示例
SQLSERVER 2005 以后提供了新的方式进行行列转换,下面是一个实例供参考: if object_id('tb') is not null drop table tbTest go ),季度 ...
- SqlServer2000下实现行列转换
SqlServer2000下实现行列转换 2011-04-06 22:07:07| 分类: SQL Server | 标签:sqlserver 2000 行列转换 sql |举报|字号 订 ...
- 简单的叙述下SQL中行列转换的小知识!
行列转换对于工作还是学习中总是不可避免的会遇到(虽然本人还尚未工作,萌萌哒的学生一枚),解决的方法也有很多,我这里就总结一下我所想解决的问题以及怎么去解决的方法, 可能网上已经有很多类似的方法了,有的 ...
随机推荐
- Linux任务调度进程crontab的使用方法和注意事项
参考文章:Linux任务调度进程crond命令的使用方法和注意事项 一.crond简介 概念 crond的概念和crontab是不可分割的.crontab是一个命令,常见于Unix和类Unix的操作系 ...
- nginx 报错 HTTP ERROR 500 (PHP数组简写模式)
同样的代码放在Apache上执行可以执行,在nginx上面就报错了. 百度出来一堆结果貌似都不对,然后只有注释代码->运行程序,一步步找到问题所在 $buffer = []; 这一步报错了 原来 ...
- QQ个人文件夹中的文件被占用,解决办法
我的情况是记住密码的账号不可以登录,不记住密码的账号确可以登录,突然就这样,我也很郁闷. 找到路径C:\Users\Public\Documents\Tencent\QQ下的UserDataInfo. ...
- Ubuntu(基于Ubuntu)中常用的apt和dpkt命令
apt-get sudo apt-get install package 安装包 sudo apt-get -f install 修复安装”-f = ——fix-missing” sudo a ...
- shell中$0,$?,$!等的特殊用法
变量说明: $$Shell本身的PID(ProcessID)$!Shell最后运行的后台Process的PID$?最后运行的命令的结束代码(返回值)$-使用Set命令设定的Flag一览$*所有参数列表 ...
- Extjs 学习总结-Ext.define自定义类
本教程整理了extjs的一些基本概念及其使用,包括自定义类(Ext.define).数据模型.代理等.本节介绍使用Ext.define自定义类 使用Ext.define自定义类 1. 首先看看js中自 ...
- kindeditor在光标处插入编辑器外的数据
页面 <div class="form-group clearfix"> <label class="control-label col-sm-3 co ...
- JAVA创建多线程
首先:线程与进程的区别是什么呢? 进程:正在运行的一个程序称之为一个进程,进程负责了内存空间的划分,从宏观的角度:windows是在同时执行多个程序 从微观的角度看,CPU是在快速的切换要执行的程序. ...
- tyvj1863 [Poetize I]黑魔法师之门
背景 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Violet星球.为了 ...
- spark安装(实战)
sparksql+hive :http://lxw1234.com/archives/2015/06/294.htm 1,安装scala http://scala-lang.org/download/ ...