Sql Server 行列转换
今天碰到一个特殊的应用场景,收集到的客流数据,数据颗粒度到了单店单小时。
现在需要统计每个门店每天的客流数据,下面开搞。
1.原始数据:
select * from yd_peopleflow
结果:
2.先用简单的SQL实现7天的数据统计
1 select shopname,[2017-12-28],[2017-12-29],[2017-12-30], 2 [2018-01-01],[2018-01-02],[2018-01-03],[2018-01-04] 3 from 4 ( 5 select shopNo,shopName,convert(varchar(100),StartDate,23) Date,Convert(decimal(28,0),isnull(InQty,0)) InQty 6 from yd_peopleflow where StartDate >=DATEADD(DAY,-7,GETDATE())) t1 7 pivot ( 8 sum(InQty) for Date 9 in([2017-12-28],[2017-12-29],[2017-12-30],[2018-01-01],[2018-01-02],[2018-01-03],[2018-01-04]) 10 ) t2
查询结果:
3.封装成存储过程
1 if exists(select 1 from sysobjects where name ='GetPeopleFlow' and xtype ='P' ) drop proc GetPeopleFlow 2 go 3 create proc GetPeopleFlow(@DateSetp varchar(20) ,@DateNumber int) 4 as 5 begin 6 declare @startDate datetime,@enddate datetime,@dateSql varchar(500),@temp datetime,@Sql NVARCHAR (MAX) 7 8 if(@DateSetp ='month') 9 begin 10 select @startDate =DATEADD(MONTH,-@DateNumber,cast(convert(varchar(10),getdate(),120) as datetime)) 11 end 12 if(@DateSetp='day') 13 begin 14 select @startDate =DATEADD(DAY,-@DateNumber,cast(convert(varchar(10),getdate(),120) as datetime)) 15 end 16 17 select @enddate =cast(convert(varchar(10),getdate(),120) as datetime) 18 19 set @dateSql ='' 20 set @temp = @startdate 21 while(@temp <=@enddate) 22 begin 23 set @dateSql = @dateSql +'['+ convert(varchar(100),@temp,23)+'],' 24 set @temp = dateadd(day,1,@temp) 25 end 26 set @dateSql = left(@dateSql,len(@dateSql)-1) 27 28 29 SET @sql ='select shopName ''门店'', '+@dateSql+'from ( 30 select shopNo,shopName,convert(varchar(100),StartDate,23) Date,Convert(decimal(28,0),isnull(InQty,0)) InQty 31 from yd_peopleflow where StartDate >=DATEADD(DAY,-7,GETDATE())) t1 32 pivot (sum(InQty) for Date in('+@dateSql+')) t2 ' 33 34 EXEC(@sql); 35 36 end 37 go
执行存储过程:
1 GetPeopleFlow 'day',3
结果:
到此,业务结束,目标达成,前端只要执行存储过程就行。
当然如果C#或者Java可以后台直接拼装成代码,就不需要数据库端拼接数据库语句了。