1. SQL Server中行列转换 Pivot UnPivot
  2. PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现
  3.  
  4. PIVOT的一般语法是:PIVOT(聚合函数(列) FOR in (…) )AS P
  5.  
  6. 完整语法:
  7.  
  8. table_source
  9.  
  10. PIVOT(
  11.  
  12. 聚合函数(value_column
  13.  
  14. FOR pivot_column
  15.  
  16. IN(<column_list>)
  17.  
  18. )
  19.  
  20. UNPIVOT用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现
  21.  
  22. 完整语法:
  23.  
  24. table_source
  25.  
  26. UNPIVOT(
  27.  
  28. value_column
  29.  
  30. FOR pivot_column
  31.  
  32. IN(<column_list>)
  33.  
  34. )
  35.  
  36. 注意:PIVOTUNPIVOTSQL Server 2005 的语法,使用需修改数据库兼容级别
  37. 在数据库属性->选项->兼容级别改为 90
  38.  
  39. 典型实例
  40.  
  41. 一、行转列
  42.  
  43. 1、建立表格
  44.  
  45. ifobject_id('tb')isnotnulldroptabletb
  46.  
  47. go
  48.  
  49. createtabletb(姓名varchar(10),课程varchar(10),分数int)
  50.  
  51. insertintotbvalues('张三','语文',74)
  52.  
  53. insertintotbvalues('张三','数学',83)
  54.  
  55. insertintotbvalues('张三','物理',93)
  56.  
  57. insertintotbvalues('李四','语文',74)
  58.  
  59. insertintotbvalues('李四','数学',84)
  60.  
  61. insertintotbvalues('李四','物理',94)
  62.  
  63. go
  64.  
  65. select*fromtb
  66.  
  67. go
  68.  
  69. 姓名 课程 分数
  70.  
  71. ---------- ---------- -----------
  72.  
  73. 张三 语文 74
  74.  
  75. 张三 数学 83
  76.  
  77. 张三 物理 93
  78.  
  79. 李四 语文 74
  80.  
  81. 李四 数学 84
  82.  
  83. 李四 物理 94
  84.  
  85. 2、使用SQL Server 2000静态SQL
  86.  
  87. --c
  88.  
  89. select姓名,
  90.  
  91. max(case课程when'语文'then分数else0end)语文,
  92.  
  93. max(case课程when'数学'then分数else0end)数学,
  94.  
  95. max(case课程when'物理'then分数else0end)物理
  96.  
  97. fromtb
  98.  
  99. groupby姓名
  100.  
  101. 姓名 语文 数学 物理
  102.  
  103. ---------- ----------- ----------- -----------
  104.  
  105. 李四 74 84 94
  106.  
  107. 张三 74 83 93
  108.  
  109. 3、使用SQL Server 2000动态SQL
  110.  
  111. --SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
  112.  
  113. --变量按sql语言顺序赋值
  114.  
  115. declare@sqlvarchar(500)
  116.  
  117. set@sql='select姓名'
  118.  
  119. select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']'
  120.  
  121. from(selectdistinct课程fromtb)a--同from tb group by课程,默认按课程名排序
  122.  
  123. set@sql=@sql+' from tb group by姓名'
  124.  
  125. exec(@sql)
  126.  
  127. --使用isnull(),变量先确定动态部分
  128.  
  129. declare@sqlvarchar(8000)
  130.  
  131. select@sql=isnull(@sql+',','')+' max(case课程when '''+课程+''' then分数else 0 end) ['+课程+']'
  132.  
  133. from(selectdistinct课程fromtb)asa
  134.  
  135. set@sql='select姓名,'+@sql+' from tb group by姓名'
  136.  
  137. exec(@sql)
  138.  
  139. 姓名 数学 物理 语文
  140.  
  141. ---------- ----------- ----------- -----------
  142.  
  143. 李四 84 94 74
  144.  
  145. 张三 83 93 74
  146.  
  147. 4、使用SQL Server 2005静态SQL
  148.  
  149. select*fromtb pivot(max(分数)for课程in(语文,数学,物理))a
  150.  
  151. 5、使用SQL Server 2005动态SQL
  152.  
  153. --使用stuff()
  154.  
  155. declare@sqlvarchar(8000)
  156.  
  157. set@sql='' --初始化变量@sql
  158.  
  159. select@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值
  160.  
  161. set@sql=stuff(@sql,1,1,'')--去掉首个','
  162.  
  163. set@sql='select * from tb pivot (max(分数) for课程in ('+@sql+'))a'
  164.  
  165. exec(@sql)
  166.  
  167. --或使用isnull()
  168.  
  169. declare@sqlvarchar(8000)
  170.  
  171. –-获得课程集合
  172.  
  173. select@sql=isnull(@sql+',','')+课程fromtbgroupby课程
  174.  
  175. set@sql='select * from tb pivot (max(分数) for课程in ('+@sql+'))a'
  176.  
  177. exec(@sql)
  178.  
  179. 二、行转列结果加上总分、平均分
  180.  
  181. 1、使用SQL Server 2000静态SQL
  182.  
  183. --SQL SERVER 2000静态SQL
  184.  
  185. select姓名,
  186.  
  187. max(case课程when'语文'then分数else0end)语文,
  188.  
  189. max(case课程when'数学'then分数else0end)数学,
  190.  
  191. max(case课程when'物理'then分数else0end)物理,
  192.  
  193. sum(分数)总分,
  194.  
  195. cast(avg(分数*1.0)asdecimal(18,2))平均分
  196.  
  197. fromtb
  198.  
  199. groupby姓名
  200.  
  201. 姓名 语文 数学 物理 总分 平均分
  202.  
  203. ---------- ----------- ----------- ----------- -----------
  204.  
  205. 李四 74 84 94 252 84.00
  206.  
  207. 张三 74 83 93 250 83.33
  208.  
  209. 2、使用SQL Server 2000动态SQL
  210.  
  211. --SQL SERVER 2000动态SQL
  212.  
  213. declare@sqlvarchar(500)
  214.  
  215. set@sql='select姓名'
  216.  
  217. select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']'
  218.  
  219. from(selectdistinct课程fromtb)a
  220.  
  221. set@sql=@sql+',sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2)) 平均分from tb group by姓名'
  222.  
  223. exec(@sql)
  224.  
  225. 3、使用SQL Server 2005静态SQL
  226.  
  227. selectm.*,n.总分,n.平均分
  228.  
  229. from
  230.  
  231. (select*fromtb pivot(max(分数)for课程in(语文,数学,物理))a)m,
  232.  
  233. (select姓名,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分
  234.  
  235. fromtb
  236.  
  237. groupby姓名)n
  238.  
  239. wherem.姓名=n.姓名
  240.  
  241. 4、使用SQL Server 2005动态SQL
  242.  
  243. --使用stuff()
  244.  
  245. --
  246.  
  247. declare@sqlvarchar(8000)
  248.  
  249. set@sql='' --初始化变量@sql
  250.  
  251. select@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值
  252.  
  253. --同select @sql = @sql + ','+课程from (select distinct课程from tb)a
  254.  
  255. set@sql=stuff(@sql,1,1,'')--去掉首个','
  256.  
  257. set@sql='select m.* , n.总分,n.平均分from
  258.  
  259. (select * from (select * from tb) a pivot (max(分数) for课程in ('+@sql+')) b) m ,
  260.  
  261. (select姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2))平均分from tb group by姓名) n
  262.  
  263. where m.姓名= n.姓名'
  264.  
  265. exec(@sql)
  266.  
  267. --或使用isnull()
  268.  
  269. declare@sqlvarchar(8000)
  270.  
  271. select@sql=isnull(@sql+',','')+课程fromtbgroupby课程
  272.  
  273. set@sql='select m.* , n.总分,n.平均分from
  274.  
  275. (select * from (select * from tb) a pivot (max(分数) for课程in ('+
  276.  
  277. @sql+')) b) m ,
  278.  
  279. (select姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2))平均分from tb group by姓名) n
  280.  
  281. where m.姓名= n.姓名'
  282.  
  283. exec(@sql)
  284.  
  285. 二、列转行
  286.  
  287. 1、建立表格
  288.  
  289. ifobject_id('tb')isnotnulldroptabletb
  290.  
  291. go
  292.  
  293. createtabletb(姓名varchar(10),语文int,数学int,物理int)
  294.  
  295. insertintotbvalues('张三',74,83,93)
  296.  
  297. insertintotbvalues('李四',74,84,94)
  298.  
  299. go
  300.  
  301. select*fromtb
  302.  
  303. go
  304.  
  305. 姓名 语文 数学 物理
  306.  
  307. ---------- ----------- ----------- -----------
  308.  
  309. 张三 74 83 93
  310.  
  311. 李四 74 84 94
  312.  
  313. 2、使用SQL Server 2000静态SQL
  314.  
  315. --SQL SERVER 2000静态SQL
  316.  
  317. select*from
  318.  
  319. (
  320.  
  321. select姓名,课程='语文',分数=语文fromtb
  322.  
  323. unionall
  324.  
  325. select姓名,课程='数学',分数=数学fromtb
  326.  
  327. unionall
  328.  
  329. select姓名,课程='物理',分数=物理fromtb
  330.  
  331. ) t
  332.  
  333. orderby姓名,case课程when'语文'then1when'数学'then2when'物理'then3end
  334.  
  335. 姓名 课程 分数
  336.  
  337. ---------- ---- -----------
  338.  
  339. 李四 语文 74
  340.  
  341. 李四 数学 84
  342.  
  343. 李四 物理 94
  344.  
  345. 张三 语文 74
  346.  
  347. 张三 数学 83
  348.  
  349. 张三 物理 93
  350.  
  351. 2、使用SQL Server 2000动态SQL
  352.  
  353. --SQL SERVER 2000动态SQL
  354.  
  355. --调用系统表动态生态。
  356.  
  357. declare@sqlvarchar(8000)
  358.  
  359. select@sql=isnull(@sql+' union all ','')+' select姓名, [课程]='
  360.  
  361. +quotename(Name,'''')+' , [分数] = '+quotename(Name)+' from tb'
  362.  
  363. fromsyscolumns
  364.  
  365. whereName!='姓名'andID=object_id('tb')--表名tb,不包含列名为姓名的其他列
  366.  
  367. orderbycolid
  368.  
  369. exec(@sql+' order by姓名')
  370.  
  371. go
  372.  
  373. 3、使用SQL Server 2005静态SQL
  374.  
  375. --SQL SERVER 2005动态SQL
  376.  
  377. select姓名,课程,分数fromtb unpivot (分数for课程in([语文],[数学],[物理])) t
  378.  
  379. 4、使用SQL Server 2005动态SQL
  380.  
  381. --SQL SERVER 2005动态SQL
  382.  
  383. declare@sqlnvarchar(4000)
  384.  
  385. select@sql=isnull(@sql+',','')+quotename(Name)
  386.  
  387. fromsyscolumns
  388.  
  389. whereID=object_id('tb')andNamenotin('姓名')
  390.  
  391. orderbyColid
  392.  
  393. set@sql='select姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in('+@sql+'))b'
  394.  
  395. exec(@sql)

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

转:MSSQL SERVER行转列 列转行的更多相关文章

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

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

  2. SQL Server 行转列,列转行

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

  3. Sql server 中将数据行转列列转行(二)

    老规矩,先弄一波测试数据,数据填充代码没有什么意义,先折叠起来: /* 第一步:创建临时表结构 */ CREATE TABLE #Student --创建临时表 ( StuName ), --学生名称 ...

  4. SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏

    SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...

  5. SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...

  6. Oracle 多行变一列的方法

    多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法. 情况是这样的.以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上. SELECT * FROM ps_vat ...

  7. 解读SQL Server 2014可更新列存储索引——存储机制

    概述 SQL Server 2014被号称是微软数据库的一个革命性版本,其性能的提升的幅度是有史以来之最. 可更新的列存储索引作为SQL Server 2014的一个关键功能之一,在提升数据库的查询性 ...

  8. SQL Server中的标识列

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...

  9. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

随机推荐

  1. InputSplit—>RecordReder—>map(key,value,context)的过程解析

    上图首先描述了在TaskTracker端Task(MapTask.ReduceTask)的执行过程,MapTask(org.apache.hadoop.mapred)首先被TaskRunner调用,然 ...

  2. .net / java /安卓des加密互通

    一 . C#.net /// <summary> /// 加密数据 /// </summary> /// <param name="Text"> ...

  3. select 下拉框的选中项的change事件

    HTML文件 <span style="float: left;">类      型:   <select id="type" class=& ...

  4. golang之archive/tar包的使用

    原文地址:http://www.niu12.com/article/36 github地址:https://github.com/ZQCard/go_api_practice // tar包实现了文件 ...

  5. 【转载】struts应用在断网情况下启动报错解决办法(java/net/AbstractPlainSocketImpl.java:178:-1)

    无意间struts应用在有网络的情况下启动正常,在断网的情况下启动报错,报错代码如下图所示: SEVERE: Exception starting filter struts2 Class: java ...

  6. C#拦截系统消息的方法-Application.AddMessageFilter

    C#拦截系统消息的方法Application.AddMessageFilter Application.AddMessageFilter这个方法可以接收系统发出的消息: 首先定义一个类,继承IMess ...

  7. opengl中VAO,VBO,IBO用法小结【转】

    http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...

  8. BindVertexbuffer

    stride 的意思是 inputstream.layout 的大小 比如 description是 pos uv normal stride 就是一组pos uv normal的大小 ns  里面 ...

  9. 【Hadoop】Hadoop MR 自定义排序

    1.概念 2.代码示例 FlowSort package com.ares.hadoop.mr.flowsort; import java.io.IOException; import org.apa ...

  10. zabbix日志监控

    一般情况下,日志最先反映出应用当前的问题,在海量日志里面找到我们异常记录,例如监控系统日志.nginx.Apache.业务日志,然后记录下来,并且根据情况报警. 1.日志监控项介绍 最主要的是监控日志 ...