一、多行转成一列(并以","隔开)

表名: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

SQL Server 行转列,列转行。多行转成一列的更多相关文章

  1. [转帖]SQL Server 索引中include的魅力(具有包含性列的索引)

    SQL Server 索引中include的魅力(具有包含性列的索引) http://www.cnblogs.com/gaizai/archive/2010/01/11/1644358.html 上个 ...

  2. SQL Server中关于基数估计如何计算预估行数的一些探讨

    关于SQL Server 2014中的基数估计,官方文档Optimizing Your Query Plans with the SQL Server 2014 Cardinality Estimat ...

  3. SQL Server 索引中include的魅力(具有包含性列的索引)

    2010-01-11 20:44 by 听风吹雨, 22580 阅读, 24 评论, 收藏, 编辑 开文之前首先要讲讲几个概念 [覆盖查询] 当索引包含查询引用的所有列时,它通常称为“覆盖查询”. [ ...

  4. SQL Server 索引中include的魅力(具有包含性列的索引)(转载)

    开文之前首先要讲讲几个概念 [覆盖查询] 当索引包含查询引用的所有列时,它通常称为“覆盖查询”.  [索引覆盖] 如果返回的数据列就包含于索引的键值中,或者包含于索引的键值+聚集索引的键值中,那么就不 ...

  5. SQL Server安全(10/11):行级别安全(Row-Level Security)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...

  6. sql server 查询出的结果集,拼接某一列赋值给一个变量

    现有表Area 如下: SELECT [Areaid] ,[Areaname] ,[Areapid] FROM [Northwind].[dbo].[Area] 查询结果如下图: 需求:用 “-“ ” ...

  7. SQL Server批量向表中插入多行数据语句

    因自己学习测试需要,需要两个有大量不重复行的表,表中行数越多越好.手动编写SQL语句,通过循环,批量向表中插入数据,考虑到避免一致问题,设置奇偶行不同.个人水平有限,如有错误,还望指正. 语句如下: ...

  8. 【sql server】"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案

    #事故现场: 1.在手动修改某表中数据是,出现如下错误提示:  已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行 2.表结构及数据: #解决方法: 1.原因分析:提示被删除的行不是唯一行, ...

  9. SQL Server查看所有表大小、表行数和占用空间信息

    一.查看表名和对应的数据行数select  a.name as '表名',b.rows as '表数据行数'from sysobjects a inner join sysindexes bon a. ...

  10. sql server选取第m行到第n行的元组

    现在有一个表Questioin,主码是qid,要求选择第m行到第n行的元组 //方法一:效率最低 //错误:如果n<m,将选取前n条数据,如果n>=m,将选取从m+1开始的n条数据 sel ...

随机推荐

  1. Island Perimeter

    You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represen ...

  2. PHP和JS判断变量是否定义

    PHP中: 通过isset(变量名)来判断,定义返回true/未定义返回false JS中: 通过typeof来判断.

  3. 使用python实现后台系统的JWT认证(转)

    今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认 ...

  4. JavaScript中错误正确处理方式,你用对了吗?

    JavaScript的事件驱动范式增添了丰富的语言,也是让使用JavaScript编程变得更加多样化.如果将浏览器设想为JavaScript的事件驱动工具,那么当错误发生时,某个事件就会被抛出.理论上 ...

  5. python中如何不区分大小写的判断一个元素是否在一个列表中

    python中判断某一个元素是否在一个列表中,可以使用关键字in 和 not in. 示例如下: 如果需要输出相应的信息,可以搭配使用if语句,这里不赘述. --------------------- ...

  6. JavaScript设计模式接口

    JavaScript中实现接口的方法有三种: 第一种,使用注释的方法实现接口 特点:(1)最简单,但是功能最弱(2)利用 interface和 implement"文字"(3)把他 ...

  7. ZOJ1654 Place the Robots

    Zoj1654 标准解法:二分匈牙利. 写法各异嘛,看不懂或者懒得看也正常,如果想了解我思路的可以和我讨论的. 在练习sap,所以还是写了一遍: #include<cstdio> #inc ...

  8. MySQL(十五)之数据备份中mysqldump详解

    前言 其实前面一篇数据备份已经是非常的详细了,这里我想单独的讲解一下mysqldump,相信很多程序员都是用过这个命令的! 一.MySQL数据库的备份与还原 1.1.MySQL数据库备份 1)语法 m ...

  9. 使用wget做站点镜像及wget的高级用法

    本文为大家介绍 使用wget做站点镜像及wget的高级用法,供大家学习参考. # wget -r -p -np -k http://xxx.edu.cn -r 表示递归下载,会下载所有的链接,不过要注 ...

  10. [http服务]

    [http服务] CentOS 6 httpd 程序环境 记录了httpd的主进程编号: v 主程序文件: /usr/sbin/httpd /usr/sbin/httpd.worker /usr/sb ...