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

https://www.cnblogs.com/gaizai/p/3753296.html

原文地址:https://www.cnblogs.com/y112102/p/3007089.html