Pivot行列互转

陌路散爱 提交于 2020-03-19 06:22:58

行转列,列转行,传统方式与pivot方式,不同的实现,同样的结果

最近在做考勤管理,有需要行转列的报表,CaseWhen老方法可以实现,但Pivot方法实现更为简便,以下是具体实现。

 1 --行转列
 2 create table T_1(Name varchar(10),LeaveType varchar(10), Days int)
 3 
 4 insert into T_1 values('张三丰','病假',20)
 5 insert into T_1 values('张无忌','婚假',3)
 6 insert into T_1 values('萧峰','探亲假',30)
 7 insert into T_1 values('段誉','事假',2)
 8 insert into T_1 values('虚竹','事假',3)
 9 
10 select * from T_1
11 
12 --case when 老用法
13 select Name,
14 
15  max(case LeaveType when '病假' then Days else 0 end) 病假,
16  max(case LeaveType when '婚假' then Days else 0 end) 婚假,
17  max(case LeaveType when '探亲假' then Days else 0 end) 探亲假,
18  max(case LeaveType when '事假' then Days else 0 end) 事假
19 from T_1
20 group by Name
21 
22 --case when 动态老用法
23 declare @sqlstr varchar(600)
24 
25 set @sqlstr='select Name'
26 select @sqlstr=@sqlstr+',max(case LeaveType when '''+LeaveType+''' then Days else 0 end) ['+LeaveType+']'
27 from(select distinct LeaveType from T_1) a
28 set @sqlstr=@sqlstr+ ' from T_1 group by Name'
29 exec(@sqlstr)
30 
31 -- 使用新用法pivot
32 select * from T_1 pivot(max(Days) for LeaveType in (病假,婚假,探亲假,事假)) a
33 
34 --使用新用法pivot动态
35 
36 declare @sqlstr varchar(6000)
37 
38 set @sqlstr=''
39 select @sqlstr=@sqlstr+','+LeaveType from T_1 group by LeaveType 
40 set @sqlstr=stuff(@sqlstr,1,1,'')
41 set @sqlstr='select * from T_1 pivot (max(Days) for LeaveType in ('+@sqlstr+')) a'
42 exec(@sqlstr)
43 
44 --列转行
45 
46 create table T_2(Name varchar(10),病假 int,婚假 int,事假 int, 探亲假 int)
47 
48 insert into T_2 values('段誉',0,0,2,0)
49 insert into T_2 values('萧峰',0,0,0,30)
50 insert into T_2 values('虚竹',0,0,3,0)
51 insert into T_2 values('张三丰',20,0,0,0)
52 insert into T_2 values('张无忌',0,3,0,0)
53 
54 select * from T_2
55 
56 --老方法 case when
57 select * from(
58  select Name,LeaveType='病假',Days=病假 from T_2
59  union all
60  select Name,LeaveType='婚假',Days=婚假 from T_2
61  union all
62  select Name,LeaveType='事假',Days=事假 from T_2
63  union all
64  select Name,LeaveType='探亲假',Days=探亲假 from T_2) t
65  where t.Days <> 0
66  order by Name
67  
68  --老方法 case when 动态
69  
70 declare @sqlstr varchar(6000)
71 select @sqlstr= isnull(@sqlstr+' union all ','')+' select Name, [LeaveType]='
72 +quotename(Name,'''')+' , [Days] = '+quotename(Name)+' from T_2'
73 from syscolumns
74 where Name!='Name' and ID=object_id('T_2') --表名tb,不包含列名为姓名的其他列
75 order by colid
76 exec('select * from ('+@sqlstr+')t where Days <> 0 order by Name')
77 
78 select * from syscolumns where ID=object_id('T_2')
79 
80 --新方法 pivot 
81 
82 select * from T_2
83 
84 select Name,LeaveType,Days from T_2 unpivot (Days for LeaveType in([病假],[婚假],[事假],[探亲假])) t
85 where days <> 0
86 
87 --新方法 pivot 动态
88 
89 declare @sqlstr varchar(6000)
90 select @sqlstr=isnull(@sqlstr+',','')+quotename(Name)
91 from syscolumns
92 where ID=object_id('T_2')and Name not in('Name')
93 order by Colid
94 set @sqlstr='select Name,[LeaveType],[Days] from T_2 unpivot ([Days] for [LeaveType] in('+@sqlstr+')) b where days<> 0'
95 exec(@sqlstr)
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!