SQL Server中行列转换 Pivot UnPivot

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)

转载于:https://www.cnblogs.com/Apq/archive/2011/09/20/Pivot.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 835. 图像重叠

1. 题目 给出两个图像 A 和 B &#xff0c;A 和 B 为大小相同的二维正方形矩阵。&#xff08;并且为二进制矩阵&#xff0c;只包含0和1&#xff09;。 我们转换其中一个图像&#xff0c;向左&#xff0c;右&#xff0c;上&#xff0c;或下滑动任何数量的单位&#xff0c;并把…

数据标准化 - scale() - Python代码

标准化 去均值&#xff0c;方差规模化 数据分析的过程中&#xff0c;比如线性规划这一类的分析&#xff0c;如果有些特征的数值远远高于或低于其他数值&#xff0c;通常称之为独立点、异常值或噪点&#xff0c;那么对于受噪点影响较大的模型就无法正确地去学习其他特征。 St…

LeetCode 813. 最大平均值和的分组(DP)

1. 题目 我们将给定的数组 A 分成 K 个相邻的非空子数组 &#xff0c;我们的分数由每个子数组内的平均值的总和构成。 计算我们所能得到的最大分数是多少。 注意我们必须使用 A 数组中的每一个数进行分组&#xff0c;并且分数不一定需要是整数。 示例: 输入: A [9,1,2,3,9…

.NET 动态脚本语言Script.NET系列文章汇总 非常精彩的应用举例

对于Script.NET,我已经写了三篇文章来介绍它&#xff0c;文章汇总如下 .NET 动态脚本语言Script.NET 入门指南 Quick Start .NET 动态脚本语言Script.NET 开发指南 .NET 动态脚本语言Script.NET 应用举例 希望这三篇文章能帮助你了解Script.NET。 下面的例子&#xff0c;继续讲…

异常值处理 - iterrows()对 DataFrame 进行遍历,并修改遍历中的异常值 - Python代码

先要有一个很简单的被命名为 data 的表&#xff1a; 第三列是一个名曰周杰伦的人历年来每个月的月薪&#xff0c;其中2016年月薪10万&#xff0c;纵观他历年来的月薪基本不超过3万&#xff08;显然他不是我的偶像胖伦&#xff09;&#xff0c;因此对于这个人来说月薪10万是有些…

LeetCode 44. 通配符匹配(DP)

1. 题目 给定一个字符串 (s) 和一个字符模式 (p) &#xff0c;实现一个支持 ? 和 * 的通配符匹配。 ? 可以匹配任何单个字符。* 可以匹配任意字符串&#xff08;包括空字符串&#xff09;。 两个字符串完全匹配才算匹配成功。 说明: s 可能为空&#xff0c;且只包含从 a-…

HtmlAgilityPack/xpath

【转载】HTML解析利器HtmlAgilityPack在网上发现了一个.NET下的HTML解析类库HtmlAgilityPack。HtmlAgilityPack是一个支持用XPath来解析HTML的类库&#xff0c;在花了一点时间学习了解HtmlAgilityPack的API和XPath之后&#xff0c;周公就做了一个简单的工具完成了这个功能&…

特征计算 -获取本周,本月初,本月末,上月同日,本季,本年初,本年末的日期 - (Python、MySQL、Oracle)

数据预处理的过程中&#xff0c;往往需要计算当前日期往前推12个月&#xff08;或者本周&#xff0c;本月&#xff0c;本季&#xff0c;本年&#xff09;中间发生的事情&#xff0c; 因此这里贴上相关处理的代码&#xff1a; Python代码&#xff1a; import datetime from d…

LeetCode 966. 元音拼写检查器(哈希)

1. 题目 在给定单词列表 wordlist 的情况下&#xff0c;我们希望实现一个拼写检查器&#xff0c;将查询单词转换为正确的单词。 对于给定的查询单词 query&#xff0c;拼写检查器将会处理两类拼写错误&#xff1a; 大小写&#xff1a;如果查询匹配单词列表中的某个单词&…

MVVM更容易内存泄露吗?

由于MVVM是把View, ViewModel, Model紧紧绑定在一起的模式&#xff0c;特别视图和视图模型通过实现观察者模式双向绑定和NotifyPropertyChanged事件&#xff0c;似乎更加容易造成内存泄露/内存不释放。网上也有这种说法。真的是这样的吗&#xff1f;我们来实际测试一下。 实际测…

分组统计 - 不同时间颗粒度下,按照秒、分、时、日、周、月、季度、年 GROUP BY 分组统计 - (MySQL)

数据处理时&#xff0c;经常需要&#xff1a;统计不同时间粒度下的数据分布情况。 例如&#xff0c;网站每天&#xff08;or每小时&#xff09;的访问量&#xff0c;周杰伦每年&#xff08;or每季度 or每月&#xff09;的收入等。 首先有一个表叫&#xff1a;table_test&…

LeetCode 971. 翻转二叉树以匹配先序遍历(DFS)

1. 题目 给定一个有 N 个节点的二叉树&#xff0c;每个节点都有一个不同于其他节点且处于 {1, …, N} 中的值。 通过交换节点的左子节点和右子节点&#xff0c;可以翻转该二叉树中的节点。 考虑从根节点开始的先序遍历报告的 N 值序列。将这一 N 值序列称为树的行程。 &…

初学Struts遇到的坑爹问题

主要页面 Action: LoginAction.java //用于处理登陆这个事件 FromBean: LoginForm.java //存储Login.jsp中传过来的表单内容 JSP:Login.jsp //登陆页面&#xff0c;提交到login.do XML配置文件&#xff1a;struts-config.xml&#xff0c;web.x…

缺失值处理 - 获取一段时间内所有日期的列表 - (Python、MySQL)

有的时候做数据清洗的时候 &#xff0c; 如果表中数据在某一天没有记录&#xff0c;但是业务要求不能有缺失日期&#xff0c;那么就需要我们将这些缺失日期补上。这个前提就是我们先要有一张包含所有日期的列表&#xff08;作为左表&#xff09;&#xff0c;供我们进行匹配&…

[Kaggle] Digit Recognizer 手写数字识别

文章目录1. Baseline KNN2. Try SVCDigit Recognizer 练习地址 相关博文&#xff1a;[Hands On ML] 3. 分类&#xff08;MNIST手写数字预测&#xff09; 1. Baseline KNN 读取数据 import pandas as pd train pd.read_csv(train.csv) X_test pd.read_csv(test.csv)特征、…

C#中的类型转换大总结

使用C#一个最常见的问题便是各种类型间的转换。我们知道&#xff0c;C#中的类型分为值类型和引用类型两大类。但是&#xff0c;有关它们间各自转换的细节描述在网上很少得到详细的回答。现在&#xff0c;我结合搜索到的部分资料整理如下&#xff1a; 1&#xff0c;问题 c#中类型…

DataFrame字符串之分割split()、清洗drop()、合并concat()、重新建立索引reset_index() - (Python)

数据建模之前&#xff0c;我们从数据部门拿到数据&#xff0c;但是这些数据的格式往往并不是我们可以直接使用的&#xff0c;比如下面表中的数据&#xff08;左&#xff1a;原数据格式&#xff09;。 原数据格式id自成一列&#xff0c;这个很好&#xff0c;但是标签和标签的置…

LeetCode 97. 交错字符串(DP)

1. 题目 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。 示例 1: 输入: s1 "aabcc", s2 "dbbca", s3 "aadbbcbcac" 输出: true示例 2: 输入: s1 "aabcc", s2 "dbbca", s3 "aadbbbaccc&qu…

浅谈 JavaScript 编程语言的编码规范--转载

原文&#xff1a;http://www.ibm.com/developerworks/cn/web/1008_wangdd_jscodingrule/ 对于熟悉 C/C 或 Java 语言的工程师来说&#xff0c;JavaScript 显得灵活&#xff0c;简单易懂&#xff0c;对代码的格式的要求也相对松散。很容易学习&#xff0c;并运用到自己的代码中。…

Power BI 数据分析可视化软件入门教程

入 门 l Power BI 的引导学习 什么是Power BI&#xff1f; Power BI 是软件服务、应用和连接器的集合&#xff0c;它们协同工作以将相关数据来源转换为连贯的视觉逼真的交互式见解。 Power BI 简单且快速&#xff0c;能够从 Excel 电子表格或本地数据库创建快速见解。同…