sql 行转列
行转列 在实际报表,统计查询业务中经常用到,自己曾经也很苦恼。 (以pivot 切入点)。
场景的一般分为静态和动态
静态的比如列 显示1-12个月 ,可以写死。
比如demo:
in里面的 1-12 注意的这里需要加上[] 号,之前看的文章都是语文,数学 体育 汉字不要, 这里是个坑
if Object_id('Tempdb..##list') is not null drop table ##list; ;with listCte as( select ItemName ,MM=yyyyMM%100, Amt= sum(Amt) from SumFixedAssets where $sqlWhere$ group by YYYYMM, ItemName ) select * into ##list from listCte pivot(sum(amt) for MM in([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) pt
--动态:
实战开始:
需求:
大概意思:类别 在所有年月 【某个值,这个是业务上根据实际需求】 显示百分
--第一步查询数据源,根据类型,年月分组 --存入临时表listAll if Object_id('Tempdb..#listAll') is not null drop table #listAll; select * into #listAll from ( select TypeName, yyyymm= convert(nvarchar(6), RestDate,112), --checkrnoqty 某个值 实际业务 知道是个值就ok checkrnoqty=cast(sum(isnull(checkrnoqty,0))/nullif(sum(isnull(orderqty,0)),0) as decimal(18,3))*100 from table1 t1 left join table1 t2 ON t1.AccId=t2.AccId and t2.IsFactoryName=1 where t1.RestDate between '2019-01-03' and '2019-05-23' group by TypeName,convert(nvarchar(6), RestDate,112) )t select * from #listAll --为了数据直观 排序一下 order by yyyymm
结果:
第2步:动态根据前面的先死后活发,取出所有的年月 存入变量,
--定义变量 存放所有的符合条件的年月 declare @sqlNianyuePivot varchar(max)=''; --注意yyyymm 数字作为列名 需要加上[] select @sqlNianyuePivot = @sqlNianyuePivot + ',[' + yyyymm+']' from ( select yyyymm= convert(nvarchar(6), yyyymm,112) from #ListAll group by convert(nvarchar(6), yyyymm,112) )t order by yyyymm --去掉首个',' set @sqlNianyuePivot = stuff(@sqlNianyuePivot, 1, 1, '') --打印 print @sqlNianyuePivot
--要执行的sql declare @execSql varchar(max)=''; set @execSql='select t.*,'+@sqlNianyuePivot+' from ( select * from #listAll t pivot(sum(checkrnoqty) for yyyymm in('+@sqlNianyuePivot+')) pt ) t' --如果发现sql有问题 ,打印出来调试 print @execSql
--最后执行定义sql变量语句
EXEC(@execSql)
--最后可能看图感觉列重复(数据源没有问题),是因为涉及到一些公司业务 隐私 ,数据源分组的时候 少了条件,
这里是没有问题的。只当笔记。
游标不推荐
alter PROCEDURE [dbo].sp AS begin declare @str varchar(200),@str2 varchar(200) set @str2='' declare cr_cursor cursor --定义游标 for select id from ss a open cr_cursor --打开游标 fetch From cr_cursor into @str while @@fetch_status=0 begin set @str2=@str+','+@str2 fetch next From cr_cursor into @str end; close cr_cursor --关闭游标 deallocate cr_cursor --释放游标 print (@str2) end
参考:
资料参考,实际工作开发
https://www.cnblogs.com/maanshancss/archive/2013/03/13/2957108.html