• 行列转换


    一、MSSQL2005之前的版本行列转换case when+(sum or max)这类聚合函数
    /*MSSQL2005版本之前行列转换*/
    ;with ScoreTab(name,subject,score) as
    (
     select 'Tom','Chinese',80
     union all
     select 'Frank','Chinese',90
     union all
     select 'Jerry','Chinese',70
     union all
     select 'Tom','English',70
     union all
     select 'Frank','English',80
     union all
     select 'Jerry','English',90
    )
    测试表数据:
    
    /*每一行做一个判断,为Chinese就不可能是English所以补0*/
    select name
       ,case subject when 'Chinese' then score else 0 end as Chinese
       ,case subject when 'English' then score else 0 end as English
     from ScoreTab
    --未聚合之前行列转换后的数据:
    
     --演变聚合sum,实现行转列 这里用max进行聚合也是一样的,因为除了0也就一个(仅限于一个人对应科目
    --数只有一次记录不会出现Tom 两次英语成绩这样的记录)
    /*
    select name
       ,sum(case subject when 'Chinese' then score else 0 end) as Chinese
       ,sum(case subject when 'English' then score else 0 end) as English
       from ScoreTab
       Group by name
    */
    聚合之后真正实现行转列的数据:
     
    ------------------------===改进版动态拼接 SQL ===----------------------
     
    05之前做法改进版--动态拼接SQL灵活实现行列转换
     
    /*2005版本之前行列转换*/
    Declare @sql nvarchar(4000)
    set @sql='
    ;with ScoreTab(name,subject,score) as
    (
     select ''Tom'',''Chinese'',80
     union all
     select ''Frank'',''Chinese'',90
     union all
     select ''Jerry'',''Chinese'',70
     union all
     select ''Tom'',''English'',70
     union all
     select ''Frank'',''English'',80
     union all
     select ''Jerry'',''English'',90
    )
    --用来准备cte,以后还是用临时表
    select name'
    ;with ScoreTab(name,subject,score) as
    (
     select 'Tom','Chinese',80
     union all
     select 'Frank','Chinese',90
     union all
     select 'Jerry','Chinese',70
     union all
     select 'Tom','English',70
     union all
     select 'Frank','English',80
     union all
     select 'Jerry','English',90
    )
    ,DistinctSubjectTab as
    (
     select distinct subject from ScoreTab
    )
    select @sql+='
       ,sum(case when subject in('''+subject+''') then score else 0 end) as '+subject
       from DistinctSubjectTab
    set @sql+='
      from ScoreTab
      Group by name'
    print @sql
    execute (@sql)
    效果图:
    

      

     
    二、MSSQL2005及之后的版本支持 pivot(行转列函数),unpivot(列转行函数)
    select * from ScoreTab pivot(sum(Score) for subject in(Chinese,English)) a
     
    /*2005版本以后行列转换*/
    Declare @sql nvarchar(4000)
    set @sql='
    ;with ScoreTab(name,subject,score) as
    (
     select ''Tom'',''Chinese'',80
     union all
     select ''Frank'',''Chinese'',90
     union all
     select ''Jerry'',''Chinese'',70
     union all
     select ''Tom'',''English'',70
     union all
     select ''Frank'',''English'',80
     union all
     select ''Jerry'',''English'',90
    )
       select * from ScoreTab pivot(sum(score) for subject in ('
    ;with ScoreTab(name,subject,score) as
    (
     select 'Tom','Chinese',80
     union all
     select 'Frank','Chinese',90
     union all
     select 'Jerry','Chinese',70
     union all
     select 'Tom','English',70
     union all
     select 'Frank','English',80
     union all
     select 'Jerry','English',90
    )
    ,DistinctSubjectTab as
    (
     select distinct subject from ScoreTab
    )
    ,PivotDistinctSubjectTab(subject) as
    (
      select  A.subject+','+B.subject FROM DistinctSubjectTab  A,DistinctSubjectTab B
      except
      SELECT  A.subject+','+B.subject FROM DistinctSubjectTab  A
                JOIN DistinctSubjectTab B
             ON A.subject=B.subject
    )
    select top 1 @sql+=subject+')) a
    '  from PivotDistinctSubjectTab
    print @sql
    execute (@sql)
    

      

     
    如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
  • 相关阅读:
    hdu 1280 排序水题
    hdu 3336 KMP+DP (仍不懂)
    懂点PS技巧,你会减少很多痛苦
    ajax返回值中有回车换行、空格的解决方法分享
    windows7系统下让所有文件夹都使用同一种视图的方法
    LINUX常用命令大全归纳篇
    js 运算符
    获取修改父页面元素
    while跟do...while的用法
    jQuery取得select选择的文本与值
  • 原文地址:https://www.cnblogs.com/Frank99/p/5951020.html
Copyright © 2020-2023  润新知