zoukankan      html  css  js  c++  java
  • 【SQL】pivot及unpivot行列转换

     pivot 用法

    /*
        第一步:创建临时表结构
    */
    CREATE TABLE Student  --创建临时表
    (
        StuName nvarchar(20),    --学生名称
        StuSubject nvarchar(20),--考试科目
        StuScore int            --考试成绩
    )
    
    /*
        第二步:写入测试数据
    */
    --张三
    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);
    
    
    
    --查询表
    select * from student
    
    
    
    
    select * from student
    
    --pivot 函数语法
    
    --table_source
    --PIVOT(
    --聚合函数(value_column)
    --FOR pivot_column
    --IN(<column_list>)
    --)
    
    select * from student
    
    --写死列名的方法
    select * from student    --数据源是谁
    pivot
    (
        max(stuscore)     --针对新转变的列名做聚合处理可sum 可max
        for stusubject in (语文,数学,英语)    --for指定哪一列的行内容准备变为新的列名 新的列名在in里面
    ) a
    
    
    --行专列加总分,平均分
    
    select m.*,n.总分,n.平均分 from (
    select * from student
    pivot
    (
        max(stuscore)
        for stusubject in (语文,数学,英语)
    ) a
    
    ) as m left join (select stuname,sum(stuScore) as 总分,cast(avg(stuScore*1.0) as decimal(18,2)) as 平均分 from student group by stuname) as n
    on m.Stuname = n.Stuname
    
    
    --动态获取列名的方法
    declare @sql varchar(8000)
    
    set @sql=''  --初始化变量@sql
    
    select @sql = @sql+','+ stusubject from student group by stusubject --变量多值赋值
    
    set @sql = stuff(@sql,1,1,'')--去掉首个','
    
    set @sql='select * from student pivot (max(StuScore) for stusubject in ('+@sql+'))a'
    
    exec(@sql)
    
    
    --动态获取列名的方法,加上总分,平均分
    
    declare @sql varchar(8000)
    
    set @sql=''  --初始化变量@sql
    
    select @sql = @sql+','+ stusubject from student group by stusubject --变量多值赋值
    
    set @sql = stuff(@sql,1,1,'')--去掉首个','
    
    set @sql='select m.*,n.总分,n.平均分 from (
    select * from student
    pivot
    (
        max(stuscore)
        for stusubject in ('+@sql+')
    ) a
    
    ) as m left join (select stuname,sum(stuScore) as 总分,cast(avg(stuScore*1.0) as decimal(18,2)) as 平均分 from student group by stuname) as n
    on m.Stuname = n.Stuname'
    exec(@sql)

    UNPIVOT用法

    -------------
    if object_id('tb')is not null drop table tb
    
    go
    
    create table tb(姓名 varchar(10),语文 int,数学 int,物理 int)
    
    insert into tb values('张三',74,83,93)
    
    insert into tb values('李四',74,84,94)
    
    go
    
    select * from tb
    
    go
    
    --UNPIVOT用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现
    
    --完整语法:
    
    --table_source
    
    --UNPIVOT(
    
    --value_column
    
    --FOR pivot_column
    
    --IN(<column_list>)
    
    --)
    
    select * from tb
    
    select * from tb   --数据源
    unpivot
    (
        分数                             --for前面是新分出来的列名
        for 课程 in (语文,数学,物理)     --for 后面跟的是科目  in 里面是科目的总计类别
    ) a
    
    
    ----动态获取行列转换表
    
    declare @sql nvarchar(4000)
    
    select @sql=isnull(@sql+',','') + quotename(Name)
    
    from syscolumns
    
    where ID=object_id('tb') and Name not in('姓名')
    
    order by Colid
    
    set @sql='select 姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in('+ @sql + '))b'
    
    exec(@sql)

    参考自:

    https://www.cnblogs.com/zhangzt/archive/2010/07/29/1787825.html

    https://www.cnblogs.com/lwhkdash/archive/2012/06/26/2562979.html

  • 相关阅读:
    后台向前台输出 换行“ ”
    Razor视图引擎输出没有编码的 Html 字符串
    C#之delegate
    C#之Action
    What's New in C# 6.0
    Git 放弃修改
    Spring.Net+Nhibernate
    nmap扫描ip段
    nginx多个if条件并且查询
    查看哪些redis命令拖慢了redis
  • 原文地址:https://www.cnblogs.com/yhnet/p/12719748.html
Copyright © 2011-2022 走看看