zoukankan      html  css  js  c++  java
  • 行列转换

    一、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)
    

      

     
    如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
  • 相关阅读:
    iOS小知识点大杂烩
    iOS 生成本地验证码
    iOS RTMP 视频直播开发笔记(1) – 采集摄像头图像
    Mac之vim普通命令使用
    工作日记(九):完整项目开发之编写前端vue代码
    HTTP常用请求头与请求体实例
    工作日记(八):完整项目开发之学习sql与学习http报文
    工作日记(七):完整项目开发之前端vue框架的搭建
    工作日记(六):完整项目开发之springboot无法启动的坑
    工作日记(五):完整项目开发之编码开始
  • 原文地址:https://www.cnblogs.com/Frank99/p/5951020.html
Copyright © 2011-2022 走看看