SQLserver行转列与列转行
行表:
| 行表 | ||
| 姓名 | 属性 | 属性值 |
| JACK | 身高 | 180 |
| JACK | 体重 | 80 |
| JACK | 年龄 | 27 |
| TOM | 身高 | 164 |
| TOM | 体重 | 59 |
| TOM | 年龄 | 20 |
列表:
| 列表 | |||
| 姓名 | 身高 | 年龄 | 体重 |
| JACK | 180 | 27 | 80 |
| TOM | 164 | 20 | 59 |
行转列就是将行表转换为列表,反之为列转行。
--==================================================================
----------------------------行转列----------------------------------
--==================================================================
-------------------------建立测试表
if exists(select * from sysobjects where ID=OBJECT_ID(N'BodyInfo') AND XTYPE='U')
DROP TABLE BodyInfo
Create Table BodyInfo
(
姓名 varchar(20),
属性 VARCHAR(20),
属性值 int
)
------------------------插入测试数据
insert into BodyInfo
select 'JACK','身高',180 union all
select 'JACK','体重',80 union all
select 'JACK','年龄',27 union all
select 'TOM','身高',164 union all
select 'TOM','体重',59 union all
select 'TOM','年龄',20 ----------------------------------------方法一:使用静态SQL
select 姓名,
max(case 属性 when '身高' then 属性值 else 0 end) AS 身高,
max(case 属性 when '体重' then 属性值 else 0 end) As 体重,
max(case 属性 when '年龄' then 属性值 else 0 end) AS 年龄
from BodyInfo group by 姓名 ----------------------------------------方法二:使用动态SQL
DECLARE @sql varchar(1000)
set @sql='select 姓名'
select @sql=@sql+',max(case 属性 when '''+属性+''' then 属性值 else 0 end) AS '+属性+''
from (select distinct 属性 from BodyInfo) a
set @sql=@sql+' from BodyInfo group by 姓名'
--print @sql
exec(@sql) ----------------------------------------方法三:使用isnull
go
/*isnull的语法是:ISNULL ( check_expression , replacement_value )
参数
check_expression 将被检查是否为 NULL的表达式。check_expression 可以是任何类型的。 replacement_value 在 check_expression 为 NULL时将返回的表达式。replacement_value 必须与 check_expresssion 具有相同的类型。 返回类型
返回与 check_expression 相同的类型。
*/
declare @sql varchar(8000) select @sql=isnull(@sql+',','')+'max(case 属性 when '''+属性+''' then 属性值 else 0 end) ['+属性+']' from (select distinct 属性 from BodyInfo) b set @sql='select 姓名,'+@sql+' from BodyInfo group by 姓名'
print @sql
exec(@sql) --------------------------------------------------方法四:使用pivot select * from BodyInfo pivot(max(属性值)for 属性 in(身高,体重,年龄))a --------------------------------------------------方法五:使用stuff扩展pivot多变量赋值 go
declare @sql varchar(8000) set @sql='' --初始化变量@sql select @sql=@sql+','+属性 from BodyInfo group by 属性--变量多值赋值 set @sql=stuff(@sql,1,1,'')--去掉首个',' set @sql='select * from BodyInfo pivot (max(属性值) for 属性 in ('+@sql+'))a' exec(@sql) ------------------------------------------方法六:使用isnull扩展pivot多变量赋值 go declare @sql varchar(8000) select @sql=isnull(@sql+',','')+属性 from BodyInfo group by 属性 set @sql='select * from BodyInfo pivot (max(属性值) for 属性 in ('+@sql+'))a' exec(@sql) --==================================================================
----------------------------列转行----------------------------------
--==================================================================
--建立测试表
if exists(select * from sysobjects where id=OBJECT_ID(N'personInfo') AND XTYPE='U')
DROP TABLE personInfo
create table personInfo
(
姓名 varchar(20),
身高 int,
年龄 int,
体重 int
)
----插入测试数据
INSERT INTO personInfo
SELECT 'JACK',180,27,80 UNION ALL
SELECT 'TOM',164,20,59 -------------------------------------------------方法一:使用CASE...WHEN select * from ( select 姓名,属性='身高',属性值=身高 from personInfo union all select 姓名,属性='体重',属性值=体重 from personInfo union all select 姓名,属性='年龄',属性值=年龄 from personInfo ) t order by 姓名,case 属性 when '身高' then 1 when '体重' then 2 when '年龄' then 3 end ------------------------------------------------调用系统表
--调用系统表。
go
declare @sql varchar(8000) select @sql=isnull(@sql+' union all ','')+' select 姓名, [属性]=' +quotename(Name,'''')+' , [属性值] = '+quotename(Name)+' from personInfo' from syscolumns where Name!='姓名'and ID=object_id('personInfo')--表名personInfo,不包含列名为姓名的其他列 order by colid set @sql=@sql+' order by 姓名'
--print @sql
exec(@sql) -----------------------------------------------使用UNPIVOT
SELECT 姓名 ,
属性 ,
属性值
FROM personInfo UNPIVOT ( 属性值 FOR 属性 IN ( [身高], [体重], [年龄] ) ) t ----------------------------------------------使用isnull扩展UNPIVOT
go
DECLARE @sql NVARCHAR(4000) SELECT @sql = ISNULL(@sql + ',', '') + QUOTENAME(name)
FROM syscolumns
WHERE id = OBJECT_ID('personInfo')
AND name NOT IN ( '姓名' )
ORDER BY colid SET @sql = 'select 姓名,[属性],[属性值] from personInfo unpivot ([属性] for [属性值] in(' + @sql
+ '))b' EXEC(@sql)
SQLserver行转列与列转行的更多相关文章
- SQLServer处理行转列和列转行
掌握SQL Server 行转列和列转行 1.列转行 数据经过计算加工后会直接生成前端图表需要的数据源,但是程序里又需要把该数据经过列转行写入中间表中,下次再查询该数据时直接从中间表查询数据. 1.1 ...
- sqlserver 行转列、列转行[转]
转自:http://www.cnblogs.com/luofuxian/archive/2012/02/23/2364328.html Sql Server 行转列.列转行 创建表: CREA ...
- SqlServer 行转列,列转行 以及PIVOT函数快速实现行转列,UNPIVOT实现列转行
一 .列转行 创建所需的数据 CREATE TABLE [StudentScores]( [UserName] NVARCHAR(20), --学生姓名 [Subject] NVARCHAR(3 ...
- 数据库-SqlServer 行转列,列转行
两篇行转列,列转行的实例文章: 第1篇:https://www.cnblogs.com/cpcpc/archive/2013/04/08/3009021.html 第2篇:https://mp.wei ...
- 做图表统计你需要掌握SQL Server 行转列和列转行
说在前面 做一个数据统计和分析的项目,每天面对着各种数据,经过存储过程从源表计算汇总后需要写入中间结果表以提高数据使用效率,那么此时就需要用到行转列和列转行. 1.列转行 数据经过计算加工后会直接生成 ...
- oracle 行转列、列转行
最近做数据处理,经常遇到需要行转列.列转行的场景,记录个非常简单实用的oracle 列转行.行转的列方法 1.行转列,基础数据如下 做行转列处理 处理SQL select user_name,max ...
- SQL 行转列和列转行
SQL 行转列和列转行 行列互转,是一个经常遇到的需求.实现的方法,有case when方式和2005之后的内置pivot和unpivot方法来实现. 在读了技术内幕那一节后,虽说这些解决方案早就用过 ...
- sql中的行转列和列转行的问题
sql中的行转列和列转行的问题 这是一个常见的问题,也是一个考的问题 1.行转列的问题 简单实例 CREATE TABLE #T ( MON1 INT, MON2 INT, MON3 INT ) G ...
- (转载)重温SQL——行转列,列转行
原文地址:http://www.cnblogs.com/kerrycode/archive/2010/07/28/1786547.html 行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通 ...
- sql 行转列 PIVOT 列转行 UNPIVOT
原文:sql 行转列 PIVOT 列转行 UNPIVOT 一: 现有表一(t_table1),想转为表二(t_table2)的格式. 表一: 年 公司 收入 2013 公司1 12 2013 公司2 ...
随机推荐
- 精通C#(第6版)
<精通C#(第6版)> 基本信息 原书名:Pro C# 5.0 and the .NET 4.5 framework,sixth edition 作者: (美)Andrew Troelse ...
- 【MongoDB】MongoDB VS SQL数据库
MongoDB和SQL数据库都能满足数据库的基本功能:1.有组织的存放数据:2.按照需求查询数据 传统的SQL数据库(e.g.Oracle, MySQL) 对表的运用不够灵活,横向扩展不太容易,而它的 ...
- 证明Dijkstra中加入S的点已经最优
语言抽象,仅供自用. 证明一个即将加入S集合的点u必然D[u]=最小值min: 假设D[u] != 最小值,那么即说明存在一条最短路径,该路径可以描述为:S集合中的一个点(至少为起始点) + 一个 ...
- 剑指Offer31 把数组排成最小的数
/************************************************************************* > File Name: 31_SortAr ...
- Linux公社资料库地址
免费下载地址在 http://linux.linuxidc.com/用户名与密码都是http://www.linuxidc.com
- PF防火墙
PF防火墙 点击认领 PF防火墙 ( 全称:Packet Filter ) 是 UNIX LIKE 系统上进行 TCP/IP 流量过滤和网络地址转换的软件系统.PF 同样也能提供 TCP/ ...
- hdu 3308 LCIS 线段树
昨天热身赛的简单版:LCIS.昨天那题用树链剖分,不知道哪里写错了,所以水了水这题看看合并.更新方式是否正确,发现没错啊.看来应该是在树链剖分求lca时写错了... 题目:给出n个数,有两种操作: 1 ...
- js上传图片及预览功能
详细内容请点击 参考了网上一些人代码写了一个上传图片及时预览的功能 <img id="imgTag" style="height: 100px;" alt ...
- Stimulsoft Reports筛选数据来绑定显示2个报表
今天用Stimulsoft Reports做报表的时候,遇到一个问题,需要一个报表中显示2个报表视图,我在百度和博客园中搜索了一下,发现这方面的资料很少,我自己最后把问题解决了之后,整理了一下给大家分 ...
- 让项目管理理论“落地”——读《IT项目经理成长手记》有感
最近利用业余时间阅读了一本好书--<IT项目经理成长手记>(潘东.韩秋泉著).本书的两位作者是神州数码(中国本土最大的整合IT服务提供商)的高管,在书中他们介绍了神州数码在IT项目管理领域 ...