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

表名: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. 洗礼灵魂,修炼python(4)--从简单案列中揭示常用内置函数以及数据类型

    上一篇说到print语句,print是可以打印任何类型到屏幕上,都有哪些类型呢? 整形(int) 长整型(long) 浮点型(float) 字符型(str) 布尔型(bool) 最常见的就这几种. 在 ...

  2. 郑厂长系列故事——排兵布阵 hdu4539(状态压缩DP)

    郑厂长系列故事——排兵布阵 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)To ...

  3. http://codeforces.com/contest/845

    A. Chess Tourney time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  4. JavaScript 版数据结构与算法(二)队列

    今天,我们要讲的是数据结构与算法中的队列. 队列简介 队列是什么?队列是一种先进先出(FIFO)的数据结构.队列有什么用呢?队列通常用来描述算法或生活中的一些先进先出的场景,比如: 在图的广度优先遍历 ...

  5. Request.QueryString("id")与Request("id")区别

    Request从几个集合取数据是有顺序的,从前到后的顺序依次是 QueryString,Form,最后是ServerVariables.Request对象按照这样的顺序依次搜索这几个集合中的变量,如果 ...

  6. 聊聊Java语言中的单例

    package com.xinke.mybatis.test; public class TestSingleton { private static TestSingleton ts = null; ...

  7. Weave Scope 容器地图 - 每天5分钟玩转 Docker 容器技术(80)

    Weave Scope 的最大特点是会自动生成一张 Docker 容器地图,让我们能够直观地理解.监控和控制容器.千言万语不及一张图,先感受一下. 下面开始实践 Weave Scope. 安装 执行如 ...

  8. Promise 对象

    Promise 对象用于处理异步请求,保存一个异步操作最终完成(或失败)的结果 语法 new Promise( /* executor */ function(resolve, reject) {.. ...

  9. Spring装配Bean之XML装配bean

    在Spring刚出现的时候,XML是描述配置的主要方式,在Spring的名义下,我们创建了无数行XML代码.在一定程度上,Spring成为了XML的同义词. 现在随着强大的自动化配置和Java代码的配 ...

  10. Coursera_程序设计与算法_计算导论与C语言基础_数组应用练习

    您也可以在我的个人博客中阅读此文章:跳转 编程题#1:求字母的个数 描述 在一个字符串中找出元音字母a,e,i,o,u出现的次数. 输入 输入一行字符串(字符串中可能有空格,请用gets(s)方法把一 ...