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

表名: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 行转列,列转行的更多相关文章

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

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

  2. SQL Server中的标识列

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

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

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

  4. SQL Server ->> ColumnStore Index(列存储索引)

    Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...

  5. Sql Server中的标识列(自增长字段)

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

  6. SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...

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

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

  8. 【转载】SQL Server行转列,列转行

    行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...

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

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

随机推荐

  1. PC、h5项目接入第三方支付宝扫码登录、扫码付款

    首先介绍一下pc项目接入支付宝扫码支付. 1.pc.移动接入支付宝扫码支付. 其实这个逻辑很简单,前端所需要处理的不是很多,后台会给一个连接,前端只需要将要支付的订单id拼接在这个连接上,然后打开跳转 ...

  2. CentOS7.2下安装php加速软件Xcache

    说明: php安装目录:/usr/local/php php.ini配置文件路径:/usr/local/php/etc/php.ini Nginx安装目录:/usr/local/nginx Nginx ...

  3. models中字段参数blank和null的用法区别

    blank当blank=True时,说明此处的数据可以不填,默认情况下为False,也就意味着默认情况下,所输入的数据不得空,blank是和页面表单有关,在页面需要输入参数的时候,如果在models里 ...

  4. 一篇入门Node.js

    目录 1.Node.js 简介 2.Node.js NPM 3.Node.js 模块 4.Node.js 事件 5.Node.js Buffer 6.Node.js 文件系统 7.Node.js St ...

  5. Problem 30

    Problem 30 https://projecteuler.net/problem=30 Surprisingly there are only three numbers that can be ...

  6. 数据类型与变量(Python学习笔记01)

    数据类型与变量 Python 中的主要数据类型有 int(整数)/float(浮点数).字符串.布尔值.None.列表.元组.字典.集合等. None 每个语言都有一个专门的词来表示空,例如 Java ...

  7. python--(协程 和 I/O多路复用)

    python--(协程 和 I/O多路复用) 一.协程 1. >>>单线程下实现并发, 最大化线程的效率, 检测 IO 并自动切换,程序级别的任务切换, 之前多进程多线程都是系统级别 ...

  8. Linux - nginx+uWSGI+django+virtualenv+supervisor发布web服务器

    目录 Linux - nginx+uWSGI+django+virtualenv+supervisor发布web服务器 crm django项目部署流程 使用supervisro启动uwsgi,退出虚 ...

  9. 【LeetCode Weekly Contest 26 Q3】Friend Circles

    [题目链接]:https://leetcode.com/contest/leetcode-weekly-contest-26/problems/friend-circles/ [题意] 告诉你任意两个 ...

  10. [luoguP1816] 忠诚(st表 || 线段树)

    传送门 其实我就是想练练 st表 本以为学了线段树可以省点事不学 st表 了 但是后缀数组中用 st表 貌似很方便 所以还是学了吧,反正也不难 ——代码 #include <cstdio> ...