SQLSERVER行转列和列转行

合集下载

SQLServer行列互转实现思路(聚合函数)

SQLServer行列互转实现思路(聚合函数)

SQLServer⾏列互转实现思路(聚合函数)有时候会碰到⾏转列的需求(也就是将列的值作为列名称),通常我都是⽤ CASE END + 聚合函数来实现的。

如下:declare @t table(StudentName nvarchar(20),Subject nvarchar(20),Score int)Insert into @t (StudentName,Subject,Score) values ( '学⽣A', '中⽂', 80 );Insert into @t (StudentName,Subject,Score) values ( '学⽣A', '数学', 78 );Insert into @t (StudentName,Subject,Score) values ( '学⽣A', '英语', 92 );Insert into @t (StudentName,Subject,Score) values ( '学⽣B', '中⽂', 89 );Insert into @t (StudentName,Subject,Score) values ( '学⽣B', '数学', 87 );Insert into @t (StudentName,Subject,Score) values ( '学⽣B', '英语', 75 );Insert into @t (StudentName,Subject,Score) values ( '学⽣C', '中⽂', 92 );Insert into @t (StudentName,Subject,Score) values ( '学⽣C', '数学', 74 );Insert into @t (StudentName,Subject,Score) values ( '学⽣C', '英语', 65 );Insert into @t (StudentName,Subject,Score) values ( '学⽣D', '中⽂', 79 );Insert into @t (StudentName,Subject,Score) values ( '学⽣D', '数学', 83 );Insert into @t (StudentName,Subject,Score) values ( '学⽣D', '英语', 81 );Insert into @t (StudentName,Subject,Score) values ( '学⽣E', '中⽂', 73 );Insert into @t (StudentName,Subject,Score) values ( '学⽣E', '数学', 84 );Insert into @t (StudentName,Subject,Score) values ( '学⽣E', '英语', 93 );Insert into @t (StudentName,Subject,Score) values ( '学⽣F', '中⽂', 79 );Insert into @t (StudentName,Subject,Score) values ( '学⽣F', '数学', 86 );Insert into @t (StudentName,Subject,Score) values ( '学⽣F', '英语', 84 );select StudentName,sum(case when Subject = N'中⽂' then Score else 0 end) Chinese,sum(case when Subject = N'数学' then Score else 0 end) Math,sum(case when Subject = N'英语' then Score else 0 end) Engilshfrom @tgroup by StudentName今天看到⼀个新的写法,pivot 可以实现相同的功能(2005才开始⽀持)。

sqlserver行列转换

sqlserver行列转换

sqlserver⾏列转换sqlserver⾏转列--创建⾏转列表及插⼊数据create table tb_RowConvertToColumn(username nvarchar(100) null,course nvarchar(100) null,score numeric(10,2) null)insert into tb_RowConvertToColumn(username,course,score) values('张三','语⽂',82)insert into tb_RowConvertToColumn(username,course,score) values('张三','数学',85)insert into tb_RowConvertToColumn(username,course,score) values('张三','外语',90)insert into tb_RowConvertToColumn(username,course,score) values('李四','语⽂',86)insert into tb_RowConvertToColumn(username,course,score) values('李四','数学',82)insert into tb_RowConvertToColumn(username,course,score) values('李四','外语',92)insert into tb_RowConvertToColumn(username,course,score) values('王五','语⽂',82)insert into tb_RowConvertToColumn(username,course,score) values('王五','数学',94)insert into tb_RowConvertToColumn(username,course,score) values('王五','外语',82)--1.静态sql⾏转列,该sql指定了转换的列头select username 姓名,MAX(case course when'语⽂'then score else0end) 语⽂,MAX(case course when'数学'then score else0end) 数学,MAX(case course when'外语'then score else0end) 外语from tb_RowConvertToColumngroup by usernameorder by username/*姓名语⽂数学外语李四 86.00 82.00 92.00王五 82.00 94.00 82.00张三 82.00 85.00 90.00*/--2.静态sql⾏转列,该sql指定了转换的列头,该语句必须sqlserver2005及以上版本才能使⽤select username 姓名,语⽂,数学,外语from tb_RowConvertToColumn pivot(max(score) for course in(语⽂,数学,外语)) a /*姓名语⽂数学外语李四 86.00 82.00 92.00王五 82.00 94.00 82.00张三 82.00 85.00 90.00*/select*from tb_RowConvertToColumn pivot(max(score)for course in (语⽂,数学,外语)) a/*username 语⽂数学外语李四 86.00 82.00 92.00王五 82.00 94.00 82.00张三 82.00 85.00 90.00*/--3.动态sql⾏转列,⾃动⽣成转换的列declare@sql nvarchar(2000)select distinct course into #tb_group from tb_RowConvertToColumn order by course desc--表头及排序select@sql=ISNULL(@sql+',','')+'MAX(case course when '''+course+''' then score else 0 end) ['+course+']'from #tb_groupset@sql='select username 姓名,'+@sql+' from tb_RowConvertToColumn a'+' group by username'exec(@sql)drop table #tb_group/*姓名语⽂外语数学李四 86.00 92.00 82.00王五 82.00 82.00 94.00张三 82.00 90.00 85.00*/--4.动态sql⾏转列,⾃动⽣成转换的列,该语句必须sqlserver2005及以上版本才能使⽤declare@sql nvarchar(2000)select@sql=ISNULL(@sql+',','')+coursefrom tb_RowConvertToColumngroup by courseset@sql='select * from tb_RowConvertToColumn pivot (max(score) for course in ('+@sql+')) a'exec(@sql)/*username 数学外语语⽂李四 82.00 92.00 86.00王五 94.00 82.00 82.00张三 85.00 90.00 82.00*/sqlserver列转⾏--创建列转⾏表及插⼊数据create table tb_ColumnConvertToRow([姓名]nvarchar(100) null,[语⽂]nvarchar(100) null,[数学]nvarchar(100) null,[外语]nvarchar(100) null)insert into tb_ColumnConvertToRow(姓名,语⽂,数学,外语) values('李四',82,92,86)insert into tb_ColumnConvertToRow(姓名,语⽂,数学,外语) values('王五',94,82,82)insert into tb_ColumnConvertToRow(姓名,语⽂,数学,外语) values('张三',85,90,82)--1.静态sql列转⾏,当列头较少时使⽤select*from(select姓名,课程='语⽂',分数=语⽂from tb_ColumnConvertToRowunion allselect姓名,课程='数学',分数=数学from tb_ColumnConvertToRowunion allselect姓名,课程='外语',分数=外语from tb_ColumnConvertToRow) a/*姓名课程分数李四语⽂ 82王五语⽂ 94张三语⽂ 85李四数学 92王五数学 82张三数学 90李四外语 86王五外语 82张三外语 82*/--2.静态sql列转⾏,当列头较少时使⽤,该语句必须sqlserver2005及以上版本才能使⽤select姓名,课程,分数from tb_ColumnConvertToRow unpivot(分数for课程in (语⽂,数学,外语)) a /*姓名课程分数李四语⽂ 82李四数学 92李四外语 86王五语⽂ 94王五数学 82王五外语 82张三语⽂ 85张三数学 90张三外语 82*/。

sqlserver行转列及列转行的使用

sqlserver行转列及列转行的使用

sqlserver⾏转列及列转⾏的使⽤在我们使⽤的数据库表中经常需要⽤到⾏列互相转换的情况,使⽤sql 的关键词 UNPIVOT(列转⾏)和PIVOT(⾏转列)可轻松实现⾏列转换。

⼀、列转⾏:员⼯⽉份排班表存储是采⽤1号~31号作为列的⽅式进⾏存储的现通过 UNPIVOT 将每天的班次⽤⾏进⾏展⽰,sql 如下:SELECT distinct t.Pb_Job_No,t.Year_Month ,convert(int, REPLACE( t.day,'day','')) as day,classno FROM Scheduling_InfoUNPIVOT(classno FOR day IN(Day1,Day2,Day3,Day4,Day5,Day6,Day7 ,Day8 ,Day9,Day10,Day11,Day12,Day13,Day14,Day15,Day16,Day17,Day18,Day19,Day20,Day21,Day22,Day23,Day24,Day25,Day26,Day27,Day28,Day29,Day30,Day31)) Twhere Year_Month='2020-05'and Pb_Job_No='0997'order by Pb_Job_No,day这⾥的关键词是UNPIVOT(classno FOR day IN('⽇期列名') ,其中 ‘day’是存储⽇期的列,classno 是存储原有班次的列查询结果如下:⼆、⾏转列:如果将上述列转⾏查询的结果表定义为 Scheduling_DayInfo,进⾏逆转为原始表,那么sql 语句为:SELECT Pb_Job_No,[1],[2] ,[3] ,[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]fromScheduling_DayInfo PIVOT ( max(classno) FOR[day]IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31]) )t结果为:此处的 in 必须是列 day 中的值,使⽤pivot 需要⽤到聚合函数(sum,count,avg,max,min 等),使⽤的场景如考试成绩 sum(score) ,年度销售业绩等,由于此处不需要统计但是⼜必须⽤聚合函数,所以使⽤max 凑合,因为这些函数可以接受字符类型的参数。

sql语句中行转列,以及列转行

sql语句中行转列,以及列转行

sql语句中⾏转列,以及列转⾏⾏转列:图1: --------------------------------------------》》》》 图2:sql执⾏原理:根据id分组,然后select后⾯创建多次查询,⽣成列信息(利⽤case语句给分group by后的语句分类)-- ⾏转列select t.id,sum(case name when'仓库1'then t.num else NULL end) 仓库1,sum(case name when'仓库2'then t.num else NULL end) 仓库2,sum(case name when'仓库3'then t.num else NULL end) 仓库3from tGROUP BY t.id;列转⾏:图1: --------------------------------------------》》》》 图2:第⼀步:sql执⾏原理:每个select语句只查某⼀个字段的值,创建多个查询,然后将多个select语句通过union链接,实现⼀条多列数据变成多⾏⼀列;⽐如⼀⾏仓库1,仓库2,仓库3 最后变成多⾏select p.id, '仓库1' name, p.`仓库1` numfrom pr punionselect p.id, '仓库2' name, p.`仓库2` numfrom pr punionselect p.id, '仓库3' name, p.`仓库3` numfrom pr p执⾏结果:第⼆步:去掉为null的,即不存在⾏select*from (select p.id, '仓库1' name, p.`仓库1` num from pr punionselect p.id, '仓库2' name, p.`仓库2` num from pr punionselect p.id, '仓库3' name, p.`仓库3` num from pr p ) T where T.num is not null order by id, name。

sqlserver行转列函数

sqlserver行转列函数

sqlserver行转列函数SQL Server中有多种方法可以将行转列,包括使用PIVOT函数、CASE语句和动态SQL等。

在接下来的讨论中,我将介绍这些方法,并提供示例来帮助您理解。

1.使用PIVOT函数:PIVOT函数是SQL Server中实现行转列功能的内置函数。

它将一个由行组成的结果集转换为具有动态列的结果集。

以下是使用PIVOT函数将行转列的示例:```sqlSELECT*FROMSELECT employee_id, department, salaryFROM employeesAS srPIVOTSUM(salary)FOR department IN ([IT], [Finance], [HR])AS piv```在上面的示例中,我们选择员工ID、部门和薪水,并使用PIVOT函数将部门作为列转换。

每个部门的薪水总和将作为新的列显示。

2.使用CASE语句:CASE语句是一种常见的在SQL中实现行转列的方法。

通过使用CASE 语句,我们可以将满足特定条件的行值转换为动态列。

以下是使用CASE语句进行行转列的示例:```sqlSELECT employee_id,MAX(CASE WHEN department = 'IT' THEN salary END) AS IT,MAX(CASE WHEN department = 'Finance' THEN salary END) AS Finance,MAX(CASE WHEN department = 'HR' THEN salary END) AS HRFROM employeesGROUP BY employee_id;```在上面的示例中,我们首先通过GROUPBY将结果按照员工进行分组,然后使用CASE语句将不同部门的薪水作为新的列。

3.使用动态SQL:动态SQL是一种使用SQL Server中的字符串操作来构建和执行动态查询的方法。

Sqlsever行转列与列转行

Sqlsever行转列与列转行

Sqlsever⾏转列与列转⾏CREATE TABLE[dbo].[Chengji]([Name]nvarchar(20) NOT NULL,[Kemu]nvarchar(20) NOT NULL,[Fenhu][int]NULL) ON[PRIMARY]GOALTER TABLE[dbo].[Chengji]ADD DEFAULT ((0)) FOR[Fenhu]GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('张三','语⽂',80)GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('张三','数学',60)GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('张三','英语',99)GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('李四','语⽂',80)GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('李四','数学',80)GOINSERT[dbo].[Chengji] ([Name], [Kemu], [Fenhu]) VALUES ('李四','英语',80)GO--1.⾏转列--⽅法⼀:select name,sum(case kemu when'语⽂'then Fenhu else0end) '语⽂',sum(case kemu when'数学'then Fenhu else0end) '数学',sum(case kemu when'英语'then Fenhu else0end) '英语'fromChengjigroup by Name--⽅法⼆:select*from Chengjipivot (sum(fenhu) for kemu in ([语⽂],[数学],[英语])) as t--2.列转⾏--创建成绩2表select*into Chengji2 from (select*from Chengjipivot (sum(fenhu) for kemu in ([语⽂],[数学],[英语])) as t) t--⽅法⼀:select name,'语⽂'科⽬,语⽂'成绩'from Chengji2 union allselect name,'数学'科⽬,数学'成绩'from Chengji2 union allselect name,'英语'科⽬,英语'成绩'from Chengji2order by name,科⽬--⽅法⼆:select*from Chengji2 UNPIVOT([fenshu]for[成绩]in ([语⽂],[数学],[英语])) as T。

sqlserver行转列函数

sqlserver行转列函数

sqlserver行转列函数
SQLServer行转列是一种在SQLServer中经常用到的转换数据的方式,它能够从原始的行数据中提取出多个列的数据,这样可以帮助用户有效地
查看数据,从而更好地进行分析和决策。

SQLServer中行转列一般有以下
三种方法:
1、使用PIVOT操作,PIVOT操作可以帮助把行转变成列,有效地更
改数据的视图,是行转列中使用最多的操作之一。

2、使用UNPIVOT操作,与PIVOT操作相反,UNPIVOT操作可以将原
始的列通过一定的处理转换为行。

3、使用With clause,With clause 可以同时兼容PIVOT和UNPIVOT
两种方法,实现行列互转,并且With clause支持行转列函数的多态化。

总的来说,SQLServer行转列的技巧非常多,无论是使用PIVOT操作,UNPIVOT操作,还是使用With clause,都可以有效地实现SQLServer中
行转列的目的,从而帮助更好地处理和分析数据,提升对数据深入分析和
理解的能力。

Sqlserver中将数据行转列列转行(一)

Sqlserver中将数据行转列列转行(一)

Sqlserver中将数据⾏转列列转⾏(⼀)在做⼀些数据分析与数据展⽰时,经常会遇到⾏转列,列转⾏的需求,今天就来总结下:在开始之前,先来创建⼀个临时表,并且写⼊⼀些测试数据:/*第⼀步:创建临时表结构*/CREATE TABLE #Student --创建临时表(StuName nvarchar(20), --学⽣名称StuSubject nvarchar(20),--考试科⽬StuScore int--考试成绩)DROP TABLE #Student --删除临时表SELECT*FROM #Student --查询所有数据/*第⼆步:写⼊测试数据*/--张三INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','语⽂',80);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','数学',75);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','英语',65);--李四INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','语⽂',36);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','数学',56);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','英语',38);--王五INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','语⽂',69);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','数学',80);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','英语',78);--赵六INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','语⽂',80);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','数学',80);INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','英语',95);数据准备好了之后,开始今天的正题:⼀:⾏转列,下⾯是转换之前与之后的截图对⽐⽅法1:使⽤Case when ⽅式SELECT StuSubject,SUM(CASE WHEN StuName='张三' THEN StuScore END) as '张三',SUM(CASE WHEN StuName='王五' THEN StuScore END) as '王五',SUM(CASE WHEN StuName='赵六' THEN StuScore END) as '赵六'FROM #StudentGROUP BY StuSubject适⽤场景:要转换成多少列确定,⽐如上⾯,已经确切知道只有张三、李四、王五、赵六四个⼈;缺点:1.如果有20个⼈,要写20个CASE 判断,写起来恶⼼,代码不优雅;2.⽆法解决列是动态产⽣的问题,⽐如按⽉份⽇期转换2⽉有可能28天,其它⽉份30天;⽅法2:使⽤PIVOT 关键字SELECT *FROM #StudentPIVOT(SUM(StuScore) FOR [StuName] IN("李四","王五","张三","赵六")) AS T适⽤场景:要转换成多少列确定,⽐如上⾯,已经确切知道只有张三、李四、王五、赵六四个⼈;缺点:1.⽆法解决列是动态产⽣的问题,⽐如按⽉份⽇期转换2⽉有可能28天,其它⽉份30天;⽅法3:使⽤PIVOT、EXEC关键Declare@StuName varchar(100);Declare@sql nvarchar(4000)--步骤1.假设列不固定,是动态产⽣的,需要先将所有列组合成⼀个长字符串,⽐如A,B,C ,SELECT@StuName=STUFF((SELECT','+ DS_descriptionFROM Base_SalaColumnWHERE DS_type='3'AND DS_means!='不参与'FOR xml path('')),1,1,'')Print@StuName--步骤2.由于动态产⽣的列,脚本不能执⾏,所以⽤Exec来执⾏,把脚本写成⼀个字符串。

sqlserver行列转换

sqlserver行列转换

sqlserver⾏列转换我们在写Sql语句的时候没经常会遇到将查询结果⾏转列,列转⾏的需求,拼接sql字符串,然后使⽤sp_executesql执⾏sql字符串是⽐较常规的⼀种做法。

但是这样做实现起来⾮常复杂,⽽在SqlServer2005中我们有了PIVOT/UNPIVOT函数可以快速实现⾏转列和列转⾏的操作。

PIVOT函数,⾏转列PIVOT函数的格式如下PIVOT(<聚合函数>([聚合列值]) FOR [⾏转列前的列名] IN([⾏转列后的列名1],[⾏转列后的列名2],[⾏转列后的列名3],.......[⾏转列后的列名N])) <聚合函数>就是我们使⽤的SUM,COUNT,AVG等Sql聚合函数,也就是⾏转列后计算列的聚合⽅式。

[聚合列值]要进⾏聚合的列名[⾏转列前的列名]这个就是需要将⾏转换为列的列名。

[⾏转列后的列名]这⾥需要声明将⾏的值转换为列后的列名,因为转换后的列名其实就是转换前⾏的值,所以上⾯格式中的[⾏转列后的列名1],[⾏转列后的列名2],[⾏转列后的列名3],......[⾏转列后的列名N]其实就是[⾏转列前的列名]每⼀⾏的值。

下⾯我们来看⼀个例⼦有⼀张表名为[ShoppingCart]有三列[Week],[TotalPrice],[GroupId],数据和表结构如下所⽰:CREATE TABLE [dbo].[ShoppingCart]([Week] [int] NOT NULL,[TotalPrice] [decimal](18, 0) NOT NULL,[GroupId] [int] NULL) ON [PRIMARY]GOALTER TABLE [dbo].[ShoppingCart] ADD DEFAULT ((0)) FOR [TotalPrice]GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (1, CAST(10 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (2, CAST(20 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (3, CAST(30 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (4, CAST(40 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (5, CAST(50 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (6, CAST(60 AS Decimal(18, 0)), 1)GOINSERT [dbo].[ShoppingCart] ([Week], [TotalPrice], [GroupId]) VALUES (7, CAST(70 AS Decimal(18, 0)), 1)GO现在我们是⽤PIVOT函数将列[WEEK]的⾏值转换为列,并使⽤聚合函数Count(TotalPrice)来统计每⼀个Week列在转换前有多少⾏数据,语句如下所⽰:select *from ShoppingCart as CPIVOT(count(TotalPrice) FOR [Week] IN([1],[2],[3],[4],[5],[6],[7])) AS T查询结果如下:我们可以看到PIVOT函数成功地将[ShoppingCart]表列[Week]的⾏值转换为了七列,并且每⼀列统计转换前的⾏数为1,这符合我们的预期结果。

SQLserver行转列列转行

SQLserver行转列列转行

SQLserver⾏转列列转⾏1.简单案例create table student(sid int primary key identity(1,1), --主键⾃增sName varchar(20), --学⽣姓名)select * from studentcreate table class(cid int primary key identity(1,1), --主键⾃增cName varchar(20))select* from classcreate table score(scid int primary key identity(1,1), --主键⾃增scName int,sid int,cid int)select * from scoreselect * from(select a.sName,b.scName,ame from student as ainner join score as b on a.[sid]=b.[sid]inner join class as c on b.cid=c.cid) as Ppivot(sum(P.scName) forame in (语⽂,数学,英语)) as T2.另⼀案例select Name as ⽔果,max(case RegionName when '北京' then Price else 0 end) 北京,max(case RegionName when '⼴州' then Price else 0 end) ⼴州from (select ,r.RegionName,rf.Price from Fruits fjoin RegionPrice rf on f.ID =rf.FruitIDjoin Regions r on rf.RegionID =r.id) tb group by Nameselect ,r.RegionName,rf.Price from Fruits fjoin RegionPrice rf on f.ID =rf.FruitIDjoin Regions r on rf.RegionID =r.idselect Name as ⽔果,case RegionName when '北京' then Price else 0 end 北京,case RegionName when '⼴州' then Price else 0 end ⼴州from (select ,r.RegionName,rf.Price from Fruits fjoin RegionPrice rf on f.ID =rf.FruitIDjoin Regions r on rf.RegionID =r.id) tbselect * from(select ,r.RegionName,rf.Price from Fruits fjoin RegionPrice rf on f.ID =rf.FruitIDjoin Regions r on rf.RegionID =r.id) tbpivot(max(tb.Price) for tb.RegionName in([⼴州],[北京])) as a。

sql server 行转列写法

sql server 行转列写法

在SQL Server 中实现行转列的方法有多种,这里介绍两种比较常用的方法。

方法一:使用PIVOT函数PIVOT函数是SQL Server中自带的一个聚合函数,可以将行数据转换为列数据。

它的使用方式如下:SELECT *FROM(SELECT 列1, 列2, 列3FROM 表名) tPIVOT(聚合函数(列值)FOR 转换列IN (列1, 列2, 列3)) p;具体来说,我们需要将要进行转换的列和对应的值用子查询的形式先查询出来,然后在最外层使用PIVOT函数进行转换。

其中,聚合函数可以是SUM、AVG、MAX等,表示对每个列值进行聚合的方式;FOR子句指定需要进行转换的列;IN子句则是列值列表。

举例来说,如果有如下一个表格:Name Subject ScoreTom Math80Tom English90Tom Chinese75Jack Math85Jack English92Jack Chinese88那么我们可以使用如下的代码进行行转列:SELECTName,[Math], [English], [Chinese]FROM(SELECT Name, Subject, ScoreFROM Scores) scoresPIVOT(AVG(Score)FOR Subject IN ([Math], [English], [Chinese])) p;转换结果如下:Name Math English ChineseTom809075Jack859288方法二:使用UNPIVOT函数UNPIVOT函数是PIVOT函数的逆操作,在SQL Server中同样可以用来实现行转列。

它的使用方式如下:SELECT 列名, 列值FROM 表名UNPIVOT(列值FOR 列名IN (列1, 列2, 列3)) unpvt;具体来说,我们需要指定要进行转换的列列表,然后在最外层使用UNPIVOT函数进行转换。

其中,列值和列名是成对出现的,表示要进行转换的每一条数据。

SQL优化之——行转列,列转行

SQL优化之——行转列,列转行

SQL优化之——⾏转列,列转⾏⾏转列,列转⾏是我们在开发过程中经常碰到的问题。

⾏转列⼀般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现。

⽤传统的⽅法,⽐较好理解。

层次清晰,⽽且⽐较习惯。

但是PIVOT 、UNPIVOT提供的语法⽐⼀系列复杂的SELECT...CASE 语句中所指定的语法更简单、更具可读性。

下⾯我们通过⼏个简单的例⼦来介绍⼀下列转⾏、⾏转列问题。

我们⾸先先通过⼀个⽼⽣常谈的例⼦,学⽣成绩表(下⾯简化了些)来形象了解下⾏转列CREATE TABLE [StudentScores]([UserName] NVARCHAR(20), --学⽣姓名[Subject] NVARCHAR(30), --科⽬[Score] FLOAT, --成绩)INSERT INTO [StudentScores] SELECT 'Nick', '语⽂', 80INSERT INTO [StudentScores] SELECT 'Nick', '数学', 90INSERT INTO [StudentScores] SELECT 'Nick', '英语', 70INSERT INTO [StudentScores] SELECT 'Nick', '⽣物', 85INSERT INTO [StudentScores] SELECT 'Kent', '语⽂', 80INSERT INTO [StudentScores] SELECT 'Kent', '数学', 90INSERT INTO [StudentScores] SELECT 'Kent', '英语', 70INSERT INTO [StudentScores] SELECT 'Kent', '⽣物', 85如果我想知道每位学⽣的每科成绩,⽽且每个学⽣的全部成绩排成⼀⾏,这样⽅便我查看、统计,导出数据SELECTUserName,MAX(CASE Subject WHEN '语⽂' THEN Score ELSE 0 END) AS '语⽂',MAX(CASE Subject WHEN '数学' THEN Score ELSE 0 END) AS '数学',MAX(CASE Subject WHEN '英语' THEN Score ELSE 0 END) AS '英语',MAX(CASE Subject WHEN '⽣物' THEN Score ELSE 0 END) AS '⽣物'FROM dbo.[StudentScores]GROUP BY UserName查询结果如图所⽰,这样我们就能很清楚的了解每位学⽣所有的成绩了接下来我们来看看第⼆个⼩列⼦。

SqlServer行转列(PIVOT),列转行(UNPIVOT)总结

SqlServer行转列(PIVOT),列转行(UNPIVOT)总结

SqlServer⾏转列(PIVOT),列转⾏(UNPIVOT)总结PIVOT⽤于将列值旋转为列名(即⾏转列)语法:table_sourcePIVOT(聚合函数(value_column)FOR pivot_columnIN(<column_list>))UNPIVOT⽤于将列明转为列值(即列转⾏)语法:table_sourceUNPIVOT(value_columnFOR pivot_columnIN(<column_list>))注意:PIVOT、UNPIVOT是SQL Server 2005的语法,使⽤需修改数据库兼容级别在数据库属性->选项->兼容级别改为 90⼀、⾏转列1、建⽴表格ifobject_id('tb')isnotnulldroptabletbgoCreate 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)goSelect * from tb2、使⽤SQL Server 2000静态SQLselect姓名,Max (case课程when'语⽂'then分数else 0 end)语⽂,Max (case课程when'数学'then分数else 0 end)数学,Max (case课程when'物理'then分数else 0 end)物理From tbGroup by姓名3、使⽤SQL Server 2000动态SQLdeclare@sqlvarchar(500)set@sql='select姓名'select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']'from(selectdistinct课程fromtb)a--同from tb group by课程,默认按课程名排序set@sql=@sql+' from tb group by姓名'exec(@sql)--使⽤isnull(),变量先确定动态部分declare@sqlvarchar(8000)select@sql=isnull(@sql+',','')+' max(case课程when '''+课程+''' then分数else 0 end) ['+课程+']'from(selectdistinct课程fromtb)asaset@sql='select姓名,'+@sql+' from tb group by姓名'exec(@sql)4、使⽤SQL Server 2005静态SQLselect*fromtb pivot(max(分数)for课程in(语⽂,数学,物理))a5、使⽤SQL Server 2005动态SQL--使⽤stuff()declare@sqlvarchar(8000)set@sql='' --初始化变量@sqlselect@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值set@sql=stuff(@sql,1,1,'')--去掉⾸个','set@sql='select * from tb pivot (max(分数) for课程in ('+@sql+'))a'exec(@sql)--或使⽤isnull()declare@sqlvarchar(8000)–-获得课程集合select@sql=isnull(@sql+',','')+课程fromtbgroupby课程set@sql='select * from tb pivot (max(分数) for课程in ('+@sql+'))a'exec(@sql)⼆、⾏转列结果加上总分、平均分1、使⽤SQL Server 2000静态SQLselect姓名,max(case课程when'语⽂'then分数else0end)语⽂,max(case课程when'数学'then分数else0end)数学,max(case课程when'物理'then分数else0end)物理,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分fromtbgroupby姓名2、使⽤SQL Server 2000动态SQL--SQL SERVER 2000动态SQLdeclare@sqlvarchar(500)set@sql='select姓名'select@sql=@sql+',max(case课程when '''+课程+''' then分数else 0 end)['+课程+']'from(selectdistinct课程fromtb)aset@sql=@sql+',sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2)) 平均分from tb group by姓名' exec(@sql)3、使⽤SQL Server 2005静态SQLselectm.*,n.总分,n.平均分from(select*fromtb pivot(max(分数)for课程in(语⽂,数学,物理))a)m,(select姓名,sum(分数)总分,cast(avg(分数*1.0)asdecimal(18,2))平均分fromtbgroupby姓名)nwherem.姓名=n.姓名4、使⽤SQL Server 2005动态SQLdeclare@sqlvarchar(8000)set@sql='' --初始化变量@sqlselect@sql=@sql+','+课程fromtbgroupby课程--变量多值赋值--同select @sql = @sql + ','+课程from (select distinct课程from tb)aset@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@sqlvarchar(8000)select@sql=isnull(@sql+',','')+课程fromtbgroupby课程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、建⽴表格ifobject_id('tb')isnotnulldroptabletbgocreatetabletb(姓名varchar(10),语⽂int,数学int,物理int)insertintotbvalues('张三',74,83,93)insertintotbvalues('李四',74,84,94)goselect*fromtb2、使⽤SQL Server 2000静态SQL--SQL SERVER 2000静态SQL。

sqlserver行列转换

sqlserver行列转换

sqlserver⾏列转换⼀、创建测试数据--创建测试表IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestRows2Columns]') AND type in (N'U')) DROP TABLE [dbo].[TestRows2Columns]GOCREATE TABLE [dbo].[TestRows2Columns]([Id] [int] IDENTITY(1,1) NOT NULL,[UserName] [nvarchar](50) NULL,[Subject] [nvarchar](50) NULL,[Source] [numeric](18, 0) NULL) ON [PRIMARY]GO --插⼊测试数据INSERT INTO [TestRows2Columns] ([UserName],[Subject],[Source])SELECT N'张三',N'语⽂',60 UNION ALLSELECT N'李四',N'数学',70 UNION ALLSELECT N'王五',N'英语',80 UNION ALLSELECT N'王五',N'数学',75 UNION ALLSELECT N'王五',N'语⽂',57 UNION ALLSELECT N'李四',N'语⽂',80 UNION ALLSELECT N'张三',N'英语',100GO⼆、⾏转列--⾏转列SELECT[UserName],[语⽂],[数学],[英语]FROM[TestRows2Columns]PIVOT(SUM([Source]) for[Subject]in([语⽂],[数学],[英语]))TBL三、多⾏查询合并到⼀⾏--多⾏转⼀⾏SELECT [UserName],[val]=STUFF( (SELECT ','+[Subject]FROM [TestRows2Columns] AS secordTableWHERE secordTable.[UserName] = firstTable.[UserName]FOR XML PATH('')) , 1 , 1 , '' )FROM [TestRows2Columns] AS firstTableGROUP BY [UserName]四、列转⾏测试数据--列转⾏CREATE TABLE Column2Line([⼯程名称] NVARCHAR(20), --⼯程名称海外供应商供给数量 INT, --海外供应商供给数量国内供应商供给数量 INT, --国内供应商供给数量南⽅供应商供给数量 INT, --南⽅供应商供给数量北⽅供应商供给数量 INT --北⽅供应商供给数量)INSERT INTO Column2LineSELECT 'A', 100, 200, 50, 50UNION ALLSELECT 'B', 200, 300, 150, 150UNION ALLSELECT 'C', 159, 400, 20, 320UNION ALLSELECT 'D',250,30,15,15列转⾏SELECT P.[⼯程名称],P.供应商类型,P.销量FROM(SELECT [⼯程名称], 海外供应商供给数量, 国内供应商供给数量,南⽅供应商供给数量, 北⽅供应商供给数量FROM Column2Line)TUNPIVOT(销量 FOR 供应商类型 IN(海外供应商供给数量, 国内供应商供给数量, 南⽅供应商供给数量, 北⽅供应商供给数量 ) ) P;。

sqlserver行转列函数

sqlserver行转列函数

sqlserver行转列函数
sqlserver行转列函数
SQL Server行转列函数
SQL Server行转列函数是SQL Server中常用的数据处理功能,它可以将行转换为列,从而实现数据的转换和操作。

SQL Server行转列函数有两种:PIVOT函数和UNPIVOT函数。

PIVOT函数是将行转换为列的函数,它可以将一行的数据转换为多行的数据,从而转换为列。

例如,如果有一个表,其中有一列存储多个值,可以使用PIVOT函数将其转换为多列,每列存储不同值。

UNPIVOT函数是将列转换为行的函数,它可以将多列的数据转换为一行的数据,从而转换为行。

例如,如果有一个表,其中有多列存储不同的值,可以使用UNPIVOT函数将其转换为一行的数据,每行存储不同的值。

SQL Server中的行转列函数主要用于数据统计、报表生成、数据分析等应用中。

它可以帮助用户快速实现数据的转换和操作,从而为用户节省大量的时间和精力,提高工作效率。

总之,SQL Server行转列函数是SQL Server中常用的数据处理功能,它可以帮助用户实现数据的转换和操作,从而提高工作效率,帮助用户提升工作效率。

sql server行转列查询语句

sql server行转列查询语句

sql server行转列查询语句SQL Server行转列查询语句是一种非常有用的查询技巧,可以将一行的数据转换为多列的形式,这对于某些业务场景非常实用。

本文将详细介绍SQL Server行转列查询语句的使用方法和注意事项,希望能帮助读者更好地掌握这一技巧。

一、什么是行转列查询语句行转列查询语句是一种将一行数据转换为多列数据的查询技巧。

在数据库中,数据通常以行的形式存储,每一行代表一个记录。

但是在某些场景下,我们需要将行数据转换为列数据,以便更好地展示和处理数据。

SQL Server提供了一些函数和关键字来实现行转列查询。

二、行转列查询的应用场景行转列查询常见的应用场景包括以下几种:1. 交叉表查询:将某一列的值作为新列,将另一列的值作为新行,用于统计和分析数据。

2. 报表生成:将多行数据按照某个字段进行分组,转换为多列数据,方便生成报表。

3. 数据展示:将一张表中的多行数据转换为一行数据,用于展示和查询。

三、行转列查询的基本语法SQL Server中实现行转列查询通常使用PIVOT和UNPIVOT关键字。

下面是行转列查询的基本语法:1. PIVOT语法:SELECT [列1], [列2], ...FROM [表名]PIVOT(聚合函数([列名])FOR [列名] IN ([列值1], [列值2], ...)) AS [别名]2. UNPIVOT语法:SELECT [列名], [值]FROM [表名]UNPIVOT([值] FOR [列名] IN ([列1], [列2], ...)) AS [别名]需要注意的是,PIVOT语句中的聚合函数可以是SUM、COUNT、AVG 等,适用于需要对数据进行统计的场景。

四、行转列查询的实际案例为了更好地理解行转列查询,下面以一个实际案例来演示如何使用行转列查询语句。

我们有一个销售数据表sales_data,包含以下列:产品名称(product_name)、区域(region)、销售额(sales_amount)。

SQLSERVERPIVOTUNPIVOT实现行列转换

SQLSERVERPIVOTUNPIVOT实现行列转换

SQLSERVERPIVOTUNPIVOT实现⾏列转换1、PIVOT、UNPIVOT介绍SQL SERVER中,可以使⽤ PIVOT 和 UNPIVOT关系运算符实现⾏列转换。

PIVOT通过将表达式某⼀列中的唯⼀值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执⾏聚合。

PIVOT运算符能够利⽤CASE语句查询实现相同的功能,但是可以⽤更少的代码就实现,⽽且看起来更漂亮。

PIVOT的语法:SELECT <⾮透视的列>, [第⼀个透视的列],...[最后⼀个透视的列] FROM (<⽣成数据的 SELECT 查询>) PIVOT (<聚合函数>(<要聚合的列>) FOR [<包含要成为列标题的值的列>] IN ( [第⼀个透视的列],... [最后⼀个透视的列]) ) AS <透视表的别名> <可选的 ORDER BY ⼦句>。

UNPIVOT运算符,PIVOT执⾏相反的操作,将表值表达式的列名转换为列值(⾏转列)。

相⽐于直接通过union来实现列转⾏,使⽤UNPIVOT 可以让sql语句变得更加简洁。

相对⽽⾔,理解难度会上升,可读性下降。

2、PIVOT实现列转⾏--创建表,填充数据CREATE TABLE #TEMP_ROW_TO_COL (NAME VARCHAR(5), COLUMNS VARCHAR(200), VALUE INT);INSERT INTO #TEMP_ROW_TO_COLVALUES ('⼩明', 'Chinese', '10'),('⼩明', 'English', '20'),('⼩明', 'Math', '30'),('⼩明', 'Physics', '40'),('⼩強', 'Chinese', '60'),('⼩強', 'English', '70'),('⼩強', 'Math', '80');--查看表数据SELECT*FROM #TEMP_ROW_TO_COL;--进⾏列转⾏SELECT*FROM #TEMP_ROW_TO_COL PIVOT (MAX(VALUE) FOR COLUMNS IN (Chinese, English, Math, Physics)) AS T;--SELECT NAME ,Chinese, English, Math, Physics FROM #TEMP_ROW_TO_COL PIVOT (MAX(VALUE) FOR COLUMNS IN (Chinese, English, Math, Physics)) AS T;--等效--删除表DROP TABLE #TEMP_ROW_TO_COL;3、UNPIVOT实现⾏转列--创建表,填充数据CREATE TABLE #TEMP_COL_TO_ROW (NAME VARCHAR(5), Chinese INT, English INT, Math INT, Physics INT);INSERT INTO #TEMP_COL_TO_ROW VALUES ('⼩明', 10, 20, 30, 40), ('⼩強', 60, 70, 80, NULL);--查看表数据SELECT*FROM #TEMP_COL_TO_ROW;--进⾏⾏转列SELECT NAME,COLUMNS,VALUE FROM #TEMP_COL_TO_ROW UNPIVOT (VALUE FOR COLUMNS IN (Chinese, English, Math, Physics)) AS T;--删除表DROP TABLE #TEMP_COL_TO_ROW;。

SQLServer中将字符串的列转行和行转列

SQLServer中将字符串的列转行和行转列

SQLServer中将字符串的列转⾏和⾏转列创建⼀个列转⾏的函数 udf_ConvertStrToTable/*-- 如将以某个字符相隔的字符串字符串转换为表-- 如字符串:Nothing,is,impossible,to,a,willing,heart-- SELECT * FROM udf_ConvertStrToTable('Nothing,is,impossible,to,a,willing,heart', ',')*/CREATE FUNCTION[dbo].[udf_ConvertStrToTable](@Str NVARCHAR(MAX),@SplitSymbol CHAR(1) =',')RETURNS@aTable TABLE(Iden INT,Item VARCHAR(500))ASBEGINDECLARE@i INTSET@i=0WHILE RIGHT(@Str, 1) =@SplitSymbolSET@Str=LEFT(@Str, LEN(@Str) -1)DECLARE@iIndex INTSET@iIndex=CHARINDEX(@SplitSymbol, @Str)WHILE@iIndex>0BEGINSET@i=@i+1INSERT INTO@aTable(Iden,Item)VALUES(@i, LEFT(@Str, @iIndex-1))SELECT@Str=SUBSTRING(@Str, @iIndex+1, 6000)SET@iIndex=CHARINDEX(@SplitSymbol, @Str)ENDIF LTRIM(RTRIM(@Str)) <>''BEGININSERT INTO@aTable(Iden,Item)VALUES(@i+1, @Str)ENDRETURNEND具体⽤法:DECLARE@Sample VARCHAR(MAX) ='Nothing,is,impossible,to,a,willing,heart';-- 列转⾏SELECT*FROM udf_ConvertStrToTable(@Sample, ',')-- ⾏转列SELECT*INTO #Temp FROM udf_ConvertStrToTable(@Sample, ',') -- 将上⾯同样的查询结果写⼊临时表 #TempSELECT STUFF((SELECT','+ A.Item FROM #Temp A ORDER BY Iden FOR XML PATH('')), 1, 1, '') AS ResultDROP TABLE #Temp-- 删除临时表执⾏效果:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1:行转列子查询,获取一定数据集结果SELECT objid,action,count(1) AS [count] FROM T_MyAttention WHERE objid IN (SELECT TOP 10 objid FROM T_MyAttentiontma GROUP BY objid ORDER BY count(1) DESC)GROUP BY objid,action下面用行转列语法获取最终结果select *from(SELECT objid,action,count(1) AS [count] FROM T_MyAttention WHERE objid IN (SELECT TOP 10 objid FROM T_MyAttentiontma GROUP BY objid ORDER BY count(1) DESC)GROUP BY objid,action) tpivot ( sum(count) for t.action in ([1],[2],[3],[4])) as ourpivot微软官方的图:2:列转行怎么把一条记录拆分成几条记录?User No. A B C1 1 21 34 241 2 42 25 16 RESULT:User No. Type Num1 1 A 211 1 B 341 1 C 241 2 A 421 2 B 251 2 C 16declare @t table(usserint ,no int ,a int,bint, c int) insert into @t select 1,1,21,34,24union all select 1,2,42,25,16SELECT usser,no,Type=attribute, Num=valueFROM @tUNPIVOT(value FOR attribute IN([a], [b], [c])) AS UPV列转行备注value FOR attribute IN([a], [b], [c])这句话中,a,b,c是列的名字,但是列名不能出现在上句的select语句中。

-结果/*usser no Type num---- --- -------- --------1 1 a 211 1 b 341 1 c 241 2 a 421 2 b 251 2 c 16*/T-SQL语句中,PIVOT命令可以实现数据表的列转行,UNPIVOT则与其相反,实现数据的行转列。

本文结合实例说明了这一过程,希望能对您有所帮助。

AD:WOT2015 互联网运维与开发者大会热销抢票一、使用PIVOT和UNPIVOT命令的SQL Server版本要求1.数据库的最低版本要求为SQL Server 2005 或更高。

2.必须将数据库的兼容级别设置为90 或更高。

3.查看我的数据库版本及兼容级别。

如果不知道怎么看数据库版本或兼容级别的话可以在SQL Server Management Studio 新建一个查询窗口输入:print @@version,运行之后在我的本机上得到:Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86)Apr 2 2010 15:53:02Copyright (c) Microsoft CorporationExpress Edition with Advanced Services on Windows NT 5.2 <X86> (Build 3790: Service Pack 2)然后我们选择一个数据库然后右键-属性选择[选项]得到下图的信息。

在确认数据库的版本和兼容级别符合1,2点的要求后你才可以接着继续往下学习。

二、使用PIVOT 实现数据表的列转行1.在这里我们先构建一个测试数据表(这里使用的是临时表,以方便我们在退出会话的时候自动删除表及其数据)首先我们先设计一个表架构为#Student { 学生编号[PK], 姓名, 性别, 所属班级 }的表,然后编写如下T-SQL--创建临时表(仅演示,表结构的不合理还请包涵)1.CREATE TABLE #Student (2.3.[学生编号] INT IDENTITY(1, 1) PRIMARY KEY,4.5.[姓名] NVARCHAR(20),6.7.[性别] NVARCHAR(1),8.9.[所属班级] NVARCHAR(20)10.11.);--给临时表插入数据1.INSERT INTO #Student (2.3.[姓名], [性别], [所属班级]4.5.)6.7.SELECT '李妹妹', '女', '初一 1班' UNION ALL 8.9.SELECT '泰强', '男', '初一 1班' UNION ALL10.11.SELECT '泰映', '男', '初一 1班' UNION ALL12.13.SELECT '何谢', '男', '初一 1班' UNION ALL14.15.SELECT '李春', '男', '初二 1班' UNION ALL16.17.SELECT '吴歌', '男', '初二 1班' UNION ALL18.19.SELECT '林纯', '男', '初二 1班' UNION ALL20.21.SELECT '徐叶', '女', '初二 1班' UNION ALL22.23.SELECT '龙门', '男', '初三 1班' UNION ALL24.25.SELECT '小红', '女', '初三 1班' UNION ALL26.27.SELECT '小李', '男', '初三 1班' UNION ALL28.29.SELECT '小黄', '女', '初三 2班' UNION ALL30.31.SELECT '旺财', '男', '初三 2班' UNION ALL32.33.SELECT '强强', '男', '初二 1班';2.查询各班级的总人数1.SELECT2.3.[所属班级] AS [班级],4.5.COUNT(1) AS [人数]6.7.FROM #Student8.9.GROUP BY [所属班级]10.11.ORDER BY [人数] DESC好了,在这里我希望把上面的表{ 班级, 人数 } 由班级[行] 的显示转换为班级[列] 的显示格式!在此你会看到第一个PIVOT示例。

是否很期待??3.编写第一个PIVOT示例1.SELECT2.3.'班级总人数:' AS [总人数],4.5.[初一 1班], [初一 2班],6.7.[初二 1班],8.9.[初三 1班], [初三 2班]10.11.FROM (12.13.SELECT14.15.[所属班级] AS [班级],16.17.[学生编号]18.19.FROM #Student20.21.) AS [SourceTable]22.23.PIVOT (24.25.COUNT([学生编号])26.27.FOR [班级] IN (28.29.[初一 1班], [初一 2班],30.31.[初二 1班],32.33.[初三 1班], [初三 2班]34.35.)36.37.) AS [PivotTable]在结果表中我们看到了对于不存在的班级初一2班它的总人数为0,这符合我们预期的结果!解释:使用POVIT首先你需要在FROM子句内定义2个表:A.一个称为源表(SourceTable)。

B.另一个称为数据透视表(PivotTable)。

语法:1.SELECT2.3.<未透视的列>,4.5.[第一个透视列] AS <列别名>,6.7.[第二个透视列] AS <列别名>,8.9....10.11.[最后一个透视列] AS <列别名>12.13.FROM (14.15.<SELECT查询>16.17.) AS <源表>18.19.PIVOT (20.21.<聚合函数>(<列>)22.23.FOR [<需要转换为行的列>] IN (24.25.[第一个透视列], [第二个透视列],26.27....28.29.[最后一个透视列]30.31.)32.33.) AS <数据透视表>34.35.<可选的ORDER BY子句>;以上的PIVOT子句内的第1…n个透视列的值均为需要转换为行的列的常量值,需要用[]括起,支持GUID,字符串及各种数字!4.下面演示一个较为高级的行转列的应用示例--使用PIVOT查询班级内的男女学生人数及总人数1.SELECT2.3.[所属班级] AS [班级],4.5.[男] AS [男生人数],6.7.[女] AS [女生人数],8.9.[男] + [女] AS [总人数]10.11.FROM (12.13.SELECT [学生编号], [所属班级], [性别] FROM #Student14.15.) AS [SourceTable]16.17.PIVOT (18.19.COUNT([学生编号])20.21.FOR [性别] IN (22.23.[男], [女]24.25.)26.27.) AS [PivotTable]28.29.ORDER BY [总人数] DESC三、使用UNPIVOT 实现的功能其实与PIVOT恰恰相反1.语法同PIVOT但是UNPIVOT的子句没有聚合函数1.SELECT2.3.<未逆透视的列>,4.5.[合并后的列] AS <列别名>,6.7.[行值的列名] AS <列别名>8.9.FROM (10.11.<SELECT查询>12.13.) AS <源表>14.15.UNPIVOT (16.17.<行值的列名>18.19.FOR <将原来多个列合并到单个列的列名> IN (20.21.[第一个合并列], [第二个合并列],22.23....24.25.[最后一个合并列]26.27.)28.29.) AS <数据逆透视表>30.31.<可选的ORDER BY子句>;2.看上面的语法感觉很浮云,不怕,这里带例子(继续使用II中用到的PIVOT表) --源表1.SELECT2.3.'班级总人数:' AS [总人数],4.5.[初一 1班], [初一 2班],6.7.[初二 1班],8.9.[初三 1班], [初三 2班]10.11.INTO #PivotTable --为了使表达意图更清晰,我把PIVOT处理后的表放到一个临时表当中12.13.FROM (14.15.SELECT16.17.[所属班级] AS [班级],18.19.[学生编号]20.21.FROM #Student22.23.) AS [SourceTable]24.25.PIVOT (26.27.COUNT([学生编号])28.29.FOR [班级] IN (30.31.[初一 1班], [初一 2班],32.33.[初二 1班],34.35.[初三 1班], [初三 2班]36.37.)38.39.) AS [PivotTable]将多个列合并到单个列的转换的语句!!! --结果1.SELECT2.3.[班级], [总人数]4.5.FROM (6.7.SELECT8.9.[初一 1班], [初一 2班],10.11.[初二 1班],12.13.[初三 1班], [初三 2班]14.15.FROM16.17.#PivotTable18.19.) AS [s]20.21.UNPIVOT (22.23.[总人数]24.25.FOR [班级] IN (26.27.[初一 1班], [初一 2班],28.29.[初二 1班],30.31.[初三 1班], [初三 2班]32.33.)34.35.) AS [un_p]执行下面代码:1.SELECT2.3.[所属班级] AS [班级],4.5.[男] AS [男生人数],6.7.[女] AS [女生人数],8.9.[男] + [女] AS [总人数]10.11.INTO #PivotTable2 --放到临时表方便查询12.13.FROM (14.15.SELECT [学生编号], [所属班级], [性别] FROM #Student16.17.) AS [SourceTable]18.19.PIVOT (20.21.COUNT([学生编号])22.23.FOR [性别] IN (24.25.[男], [女]26.27.)28.29.) AS [PivotTable]30.31.ORDER BY [总人数] DESC32.33.SELECT34.35.[班级],36.37.[男生或女生人数],38.39.[性别],40.41.[总人数]42.43.FROM (44.45.SELECT [班级], [男生人数], [女生人数], [总人数] FROM #PivotTable246.47.) AS [s]48.49.UNPIVOT (50.51.[男生或女生人数]52.53.FOR [性别] IN (54.55.[男生人数],56.57.[女生人数]58.59.)60.61.) AS [un_p]或者将性别和人数合并到一个列当中:1.SELECT2.3.[班级],4.5.[性别] + ': ' + CAST([男生或女生人数] AS NVARCHAR(1)) AS [男生或女生人数],6.7.[总人数]8.9.FROM (10.11.SELECT [班级], [男生人数], [女生人数], [总人数] FROM #PivotTable212.13.) AS [s]14.15.UNPIVOT (16.17.[男生或女生人数]18.19.FOR [性别] IN (20.21.[男生人数],22.23.[女生人数]24.25.)26.27.) AS [un_p]关于PIVOT和UNPIVOT命令的使用就介绍到这里,如果想了解更多SQL的知识可以去看看这里的文章:/sqlserver/,绝对不会让您失望的哦!。

相关文档
最新文档