SQL Server 行转列,列转行
一、多行转成一列(并以","隔开)
表名:A
表数据:

想要的查询结果:

查询语句:

SELECT name ,
value = ( STUFF(( SELECT ',' + value
FROM A
WHERE name = Test.name
FOR
XML PATH('')
), 1, 1, '') )
FROM A AS Test
GROUP BY name;

PS:STUFF语句就是为了去掉第一个【逗号】
附STUFF用法:(从原字符的第二个开始共三个字符替换为后面的字符)
SELECT STUFF('abcdef', 2, 3, 'ijklmn');
查询结果:aijklmnef
二、一列转成多行
表名:tb
表数据:

想要的结果:

查询语句:
SELECT a.[name],b.[value]
FROM (SELECT [name],[value]=CAST('<v>'+REPLACE([value],',','</v><v>')+'</v>' AS xml) FROM tb) a
OUTER APPLY (SELECT [value]=T.C.value('.','varchar(50)') FROM a.[value].nodes('/v') AS T(C)) b
三、行转列(转自大神张志涛的博客 http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html)
1、建立表格

IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb
go
CREATE TABLE tb(姓名 VARCHAR(10),课程 VARCHAR(10),分数 INT)
INSERT INTO tb VALUES('张三','语文',74)
INSERT INTO tb VALUES('张三','数学',83)
INSERT INTO tb VALUES('张三','物理',93)
INSERT INTO tb VALUES('李四','语文',74)
INSERT INTO tb VALUES('李四','数学',84)
INSERT INTO tb VALUES('李四','物理',94)
go
SELECT * FROM tb


2、使用SQL Server 2000静态SQL

SELECT 姓名, max(CASE 课程 WHEN '语文' THEN 分数 ELSE 0 end)语文, max(CASE 课程 WHEN '数学' THEN 分数 ELSE 0 end)数学, max(CASE 课程 WHEN '物理' THEN 分数 ELSE 0 end)物理 FROM tb GROUP BY 姓名


3、使用SQL Server 2005静态SQL
SELECT *
FROM tb PIVOT( MAX(分数) FOR 课程 IN ( 语文, 数学, 物理 ) ) a;

4、使用SQL Server 2005动态SQL

--使用stuff()
DECLARE @sql VARCHAR(8000)
SET @sql='' --初始化变量@sql
SELECT @sql=@sql+','+课程 FROM tb GROUP BY 课程 --变量多值赋值
SET @sql=stuff(@sql,1,1,'')--去掉首个','
SET @sql='select * from tb pivot (max(分数) for 课程 in ('+@sql+'))a'
exec(@sql)
--或使用isnull()
DECLARE @sql VARCHAR(8000)
SELECT @sql=isnull(@sql+',','')+课程 FROM tb GROUP BY 课程
SET @sql='select * from tb pivot (max(分数) for 课程 in ('+@sql+'))a'
exec(@sql)

四、行转列结果加上总分、平均分
1、使用SQL Server 2000静态SQL

SELECT 姓名, max(CASE 课程 WHEN '语文' THEN 分数 ELSE 0 end)语文, max(CASE 课程 WHEN '数学' THEN 分数 ELSE 0 end)数学, max(CASE 课程 WHEN '物理' THEN 分数 ELSE 0 end)物理, sum(分数)总分, cast(avg(分数*1.0)AS DECIMAL(18,2))平均分 FROM tb GROUP BY 姓名


2、使用SQL Server 2000动态SQL

DECLARE @sql VARCHAR(500) SET @sql='select 姓名' SELECT @sql=@sql+',max(case 课程 when '''+课程+''' then 分数 else 0 end)['+课程+']' from(SELECT DISTINCT 课程 FROM tb)a SET @sql=@sql+',sum(分数) 总分,cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名' exec(@sql)

3、使用SQL Server 2005静态SQL

SELECT m.*,n.总分,n.平均分 from (SELECT * FROM tb pivot(max(分数)FOR 课程 IN(语文,数学,物理))a)m, (SELECT 姓名,sum(分数) 总分,cast(avg(分数*1.0)AS DECIMAL(18,2))平均分 FROM tb GROUP BY 姓名)n WHERE m.姓名=n.姓名

4、使用SQL Server 2005动态SQL

--使用stuff()
--
DECLARE @sql VARCHAR(8000)
SET @sql='' --初始化变量@sql
SELECT @sql=@sql+','+课程 FROM tb GROUP BY 课程 --变量多值赋值
--同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 @sql VARCHAR(8000)
SELECT @sql=isnull(@sql+',','')+课程 FROM tb GROUP BY 课程
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、建立表格

IF OBJECT_ID('tb')IS NOT NULL DROP TABLE tb
go
CREATE TABLE tb(姓名 VARCHAR(10),语文 INT,数学 INT,物理 INT)
INSERT INTO tb VALUES('张三',74,83,93)
INSERT INTO tb VALUES('李四',74,84,94)
go
SELECT * FROM tb
go


2、使用SQL Server 2000静态SQL

--SQL SERVER 2000静态SQL。 SELECT * FROM ( SELECT 姓名,课程='语文',分数=语文 FROM tb UNION ALL SELECT 姓名,课程='数学',分数=数学 FROM tb UNION ALL SELECT 姓名,课程='物理',分数=物理 FROM tb ) t ORDER BY 姓名,CASE 课程 WHEN '语文' THEN 1 WHEN '数学' THEN 2 WHEN '物理' THEN 3 end


2、使用SQL Server 2000动态SQL

--SQL SERVER 2000动态SQL。
--调用系统表动态生态。
DECLARE @sql VARCHAR(8000)
SELECT @sql=isnull(@sql+' union all ','')+' select 姓名, [课程]='
+quotename(Name,'''')+' , [分数] = '+quotename(Name)+' from tb'
FROM syscolumns
WHERE Name!='姓名' AND ID=object_id('tb')--表名tb,不包含列名为姓名的其他列
ORDER BY colid
exec(@sql+' order by 姓名')
go

3、使用SQL Server 2005静态SQL
--SQL SERVER 2005动态SQL SELECT 姓名,课程,分数 FROM tb unpivot (分数 FOR 课程 IN([语文],[数学],[物理])) t
4、使用SQL Server 2005动态SQL

--SQL SERVER 2005动态SQL
DECLARE @sql NVARCHAR(4000)
SELECT @sql=isnull(@sql+',','')+quotename(Name)
FROM syscolumns
WHERE ID=object_id('tb')AND Name NOT IN('姓名')
ORDER BY Colid
SET @sql='select 姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in('+@sql+'))b'
exec(@sql)

再次感谢!张志涛
转自:http://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html
转载: https://www.cnblogs.com/no27/p/6398130.html
SQL Server 行转列,列转行的更多相关文章
- SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...
- SQL Server中的标识列
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: .列的数据类型为不带小数的数值类型 .在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server 2016:内存列存储索引
作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...
- SQL Server ->> ColumnStore Index(列存储索引)
Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...
- Sql Server中的标识列(自增长字段)
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...
- SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...
- SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏
SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...
- 【转载】SQL Server行转列,列转行
行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...
- SQL Server 行转列,列转行。多行转成一列
一.多行转成一列(并以","隔开) 表名:A 表数据: 想要的查询结果: 查询语句: SELECT name , value = ( STUFF(( SELECT ',' + va ...
随机推荐
- todey
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> 框架集fromset ...
- mitmproxy安装与使用
mitmproxy安装与使用 (抓包,中间人代理工具.支持SSL) 在开发微信公端的时候开发调试只能用浏览器自带开发工具,本来移动端可以用用fiddler.wireshark等工具来抓包,但是自从改用 ...
- Qt Creator 中文乱码问题
一. Qt 4 乱码问题 解决方案 1. 在Qt 中 快捷菜单选项功能中 Edit(编辑) --> Select Encoding...(选择编码) 选择载入(显示)编码和储存编码,要解决中文 ...
- 利用open MP获取计算机核心数量的方法
openMP是一款普遍通用的并行计算编程模型,使用它通常能够充分利用多核计算的优势. 以下是一种能够测试核心数量的方法: std::cout << "parallel begin ...
- 10.mysql事务管理及python操作
在用户操作MySQL过程中,对于一般简单的业务逻辑或中小型程序而言,无需考虑应用MySQL事务.但在比较复杂的情况下,往往用户在执行某些数据操作过程中,需要通过一组SQL语句执行多项并行业务逻辑或程序 ...
- 机器学习中jupyter lab的安装方法以及使用的命令
安装JupyterLab使用pip安装: pip install jupyterlab# 必须将用户级目录添加 到环境变量才能启动pip install --userbinPATHjupyter la ...
- Keil MDK下如何设置非零初始化变量(复位后变量值不丢失)
一些工控产品,当系统复位后(非上电复位),可能要求保持住复位前RAM中的数据,用来快速恢复现场,或者不至于因瞬间复位而重启现场设备.而keil mdk在默认情况下,任何形式的复位都会将RAM区的非初始 ...
- 【Codeforces 126B】Password
[链接] 我是链接,点我呀:) [题意] 给你一个字符串s 让你从中选出来一个字符串t 这个字符串t是s的前缀和后缀 且在除了前缀和后缀之外的中间部位出现过. 且要求t的长度最长. 让你输出这个字符串 ...
- [cogs461] [网络流24题#10] 餐巾 [网络流,最小费用最大流]
建图:从源点向第一层连边,第一层表示当天用掉多少餐巾,第二层表示当天需要多少餐巾,所以注意购买餐巾的边容量为无穷大,要从源点开始连向第二层的点,每天可能有剩余,在第一层内表示为流入第二天的节点.具体见 ...
- Human Gene Functions POJ 1080 最长公共子序列变形
Description It is well known that a human gene can be considered as a sequence, consisting of four n ...