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 的语法,使用需修改数据库兼容级别 ? 典型实例 一、行转列 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 姓名? ---------- --------------------- 张三? 张三? 张三? 李四? 李四? 李四? ? 2、使用SQLServer 2000静态SQL --c select姓名, ? ? ? fromtb groupby姓名 姓名? ---------- ---------------------- ----------- 李四? 张三? ? 3、使用SQLServer 2000动态SQL --SQLSERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同) --变量按sql语言顺序赋值 declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case课程when'''+课程+'''? from(selectdistinct课程fromtb)a--同fromtb group by课程,默认按课程名排序 set@sql=@sql+'from tb group by姓名' exec(@sql) ? --使用isnull(),变量先确定动态部分 declare@sqlvarchar(8000) select@sql=isnull(@sql+',','')+'max(case课程when'''+课程+'''then分数else0 end) ['+课程+']' from(selectdistinct课程fromtb)asa? set@sql='select姓名,'+@sql+'from tb group by姓名' exec(@sql) 姓名? ---------- ---------------------- ----------- 李四? 张三? ? 4、使用SQLServer 2005静态SQL select*fromtb? ? 5、使用SQL Server2005动态SQL --使用stuff() declare@sqlvarchar(8000) set@sql=''? select@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值 set@sql=stuff(@sql,1,'')--去掉首个',' set@sql='select* from tb? exec(@sql) ? --或使用isnull() declare@sqlvarchar(8000) –-获得课程集合 select@sql=isnull(@sql+','')+课程fromtbgroupby课程? set@sql='select* from tb? exec(@sql) ? 二、行转列结果加上总分、平均分 1、使用SQLServer 2000静态SQL --SQLSERVER 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姓名 姓名? ---------- ---------------------- ----------- ----------- 李四? 张三? ? 2、使用SQLServer 2000动态SQL --SQLSERVER 2000动态SQL declare@sqlvarchar(500) set@sql='select姓名' select@sql=@sql+',max(case课程when'''+课程+'''? from(selectdistinct课程fromtb)a set@sql=@sql+',sum(分数)总分,cast(avg(分数*1.0)as decimal(18,2))? exec(@sql) ? 3、使用SQLServer 2005静态SQL selectm.*,n.总分,n.平均分 from (select*fromtb? (select姓名,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分 fromtb groupby姓名)n wherem.姓名=n.姓名 ? 4、使用SQL Server2005动态SQL --使用stuff() -- declare@sqlvarchar(8000) set@sql=''? select@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值 --同select@sql = @sql + ','+课程from(select distinct课程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) ? --或使用isnull() declare@sqlvarchar(8000) select@sql=isnull(@sql+','')+课程fromtbgroupby课程 set@sql='selectm.*,n.平均分from (select *from (select * from tb) a pivot (max(分数)for课程in('+ ? (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 姓名? ---------- ---------------------- ----------- 张三? 李四? ? 2、使用SQLServer 2000静态SQL --SQLSERVER 2000静态SQL。 select*from ( ? ? ? ? ? )t orderby姓名,case课程when'语文'then1when'数学'then2when'物理'then3end 姓名? ---------- --------------- 李四? 李四? 李四? 张三? 张三? 张三? ? 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')--表名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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 关于SQLServer2005的学习笔记——自定义分组的实现
- sql-server – 在表名中添加’tbl’前缀真的有问题吗?
- winform OLEDB连接SQLSERVER 连接字符串出错
- sql-server – 如何在Express 4 Web应用程序中跨多个路由使
- 带你熟悉SQLServer2016中的System-Versioned Temporal Tabl
- sql-server – 无法使用SQL Server管理控制台连接到远程SQL
- sql-server-2008 – SQL Server 2008的问题 – “客户端无法
- sql – 使用输出在merge语句中设置变量
- SQLServer 行列转换
- SQLAlchemy通过关联对象声明多对多自连接