zoukankan      html  css  js  c++  java
  • Sql server 中将数据行转列列转行(一)

     在做一些数据分析与数据展示时,经常会遇到行转列,列转行的需求,今天就来总结下:

    在开始之前,先来创建一个临时表,并且写入一些测试数据:

    /*
        第一步:创建临时表结构
    */
    CREATE TABLE #Student  --创建临时表
    (
        StuName nvarchar(20),    --学生名称
        StuSubject nvarchar(20),--考试科目
        StuScore int            --考试成绩
    )
    DROP TABLE #Student      --删除临时表
    SELECT * FROM #Student   --查询所有数据
    
    
    
    
    /*
        第二步:写入测试数据
    */
    --张三
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','语文',80);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','数学',75);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','英语',65);
    --李四
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','语文',36);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','数学',56);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','英语',38);
    --王五
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','语文',69);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','数学',80);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','英语',78);
    --赵六
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','语文',80);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','数学',80);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','英语',95);
    复制代码
    /*
        第一步:创建临时表结构
    */
    CREATE TABLE #Student  --创建临时表
    (
        StuName nvarchar(20),    --学生名称
        StuSubject nvarchar(20),--考试科目
        StuScore int            --考试成绩
    )
    DROP TABLE #Student      --删除临时表
    SELECT * FROM #Student   --查询所有数据
    
    
    
    
    /*
        第二步:写入测试数据
    */
    --张三
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','语文',80);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','数学',75);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('张三','英语',65);
    --李四
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','语文',36);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','数学',56);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('李四','英语',38);
    --王五
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','语文',69);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','数学',80);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('王五','英语',78);
    --赵六
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','语文',80);  
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','数学',80);
    INSERT INTO #Student(StuName,StuSubject,StuScore) values ('赵六','英语',95);
    复制代码

    数据准备好了之后,开始今天的正题:

    一:行转列,下面是转换之前与之后的截图对比

     方法1:使用Case when 方式

    SELECT StuSubject
        ,SUM(CASE WHEN StuName='张三' THEN StuScore END) as '张三'
        ,SUM(CASE WHEN StuName='王五' THEN StuScore END) as '王五'
        ,SUM(CASE WHEN StuName='赵六' THEN StuScore END) as '赵六'
    FROM #Student
    GROUP BY StuSubject

    适用场景:要转换成多少列确定,比如上面,已经确切知道只有张三、李四、王五、赵六 四个人;

    缺点:1.如果有20个人,要写20个CASE 判断,写起来恶心,代码不优雅;

               2.无法解决列是动态产生的问题,比如按月份日期转换2月有可能28天,其它月份30天;

    方法2:使用PIVOT 关键字

    SELECT *
    FROM #Student
    PIVOT(SUM(StuScore) FOR [StuName] IN("李四","王五","张三","赵六")) AS T 

    适用场景:要转换成多少列确定,比如上面,已经确切知道只有张三、李四、王五、赵六 四个人;

    缺点:1.无法解决列是动态产生的问题,比如按月份日期转换2月有可能28天,其它月份30天;

    方法3:使用PIVOT、EXEC关键

    复制代码
    Declare @StuName varchar(100);
    Declare @sql nvarchar(4000)
    --步骤1.假设列不固定,是动态产生的,需要先将所有列组合成一个长字符串,比如A,B,C ,
    下面的写法只能在SQL server2017中运行,更多将多行字段合并成一个字段方法参考:https://www.cnblogs.com/Rawls/p/10758788.html SELECT @StuName='"'+STRING_AGG(StuName,'","')+'"' FROM ( SELECT StuName from #Student GROUP BY StuName ) AS TE --Print @StuName --步骤2.由于动态产生的列,脚本不能执行,所以用Exec来执行,把脚本写成一个字符串。 SET @sql=' SELECT * FROM #Student PIVOT(SUM(StuScore) FOR [StuName] IN('+@StuName+')) AS T ' --步骤3.执行脚本 Exec(@sql)
    复制代码

     适用场景:可以解决列是动态产生的问题,不然这样的写法,太曲线救国了,很长一堆代码,

                       管你2月是28天还是100天,只要在步骤1中拼接起来就搞定了;

  • 相关阅读:
    C# Note23: 如何自定义类型使用foreach循环
    C# Note22: 《Effective C#》笔记
    C# Note21: 扩展方法(Extension Method)及其应用
    C# Note20: 制作延时改变显示的标题栏
    C# Note19: Windows安装包制作实践
    Python Note1: Pycharm的安装与使用
    java Html&JavaScript面试题:HTML 的 form 提交之前如何验证数值文本框的内容全部为数字? 否则的话提示用户并终止提交?
    java Html&JavaScript面试题:用table显示n条记录,每3行换一次颜色,即1,2,3用红色字体,4,5,6用绿色字体,7,8,9用红颜色字体。
    java Html&JavaScript面试题:判断第二个日期比第一个日期大
    java算法面试题:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
  • 原文地址:https://www.cnblogs.com/itchenguo/p/13181770.html
Copyright © 2011-2022 走看看