行转列,列转行,传统方式与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)
来源:https://www.cnblogs.com/JJ.Net/p/4221928.html