• Oracle——行转列与列转行


    行转列

    把某一个字段的值作为唯一值,然后另外一个字段的行值转换成它的列值

    转换过程大致如下所示:
    在这里插入图片描述
    通常情况下,采取group by 唯一字段进行分组,然后依据不同的列进行判断输出就能转换。

    创建表和增加测试数据

    建表语句和增加测试数据sql如下所示:

    create table XJ_TEST_LtoH(
          stuid varchar(20),
          stuname varchar(40),
          coursename varchar(40),
          score int
    );
    
    
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201001','张三','数学',40);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201001','张三','语文',50);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201001','张三','理综',120);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201011','李四','数学',32);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201011','李四','语文',45);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201011','李四','理综',123);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201031','王五','数学',54);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201031','王五','语文',56);
    insert into XJ_TEST_LtoH(stuid,Stuname,coursename,score)
    values('sc202201031','王五','理综',100);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    执行完毕后,数据库中当前的数据结构如下:
    在这里插入图片描述

    同所属的类,对应不同的值,采取不同列进行存储。

    方式一:先分组,再统计平铺

    将数据根据学员名分组,将学科成绩平铺展示。sql如下所示:

    -- 方式一:先分组,再单元拆分
    select 
    t.stuid,
    t.stuname ,
    sum(decode(t.coursename,'数学',t.score,0)) "数学",
    sum(decode(t.coursename,'语文',t.score,0)) "语文",
    sum(decode(t.coursename,'理综',t.score,0)) "理综"
    from XJ_TEST_LtoH t group by t.stuname,t.stuid;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    方式二:使用Oracle11g自带函数PIVOT实现

    Oracle11g及以后自带函数PIVOT就能实现上述的效果,且代码量很小。

    select * fromPIVOT (
    	sum(xxx /**行转列需要显示数据的列**/) 
    	for 
    	XXX   /**需要行转列的列**/ 
    	in(mm,nn) /**转换后列的值**/
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    具体的使用方式,如下:

    -- 方式二:Oracle11g之后提供了自带函数PIVOT
    select * from XJ_TEST_LtoH 
    pivot (
          sum(score /**行转列需要显示数据的列**/) 
          for
          coursename /**需要行转列的列**/ 
          in('语文' as 语文,'数学' as 数学,'理综' as 理综) /**转换后列的值**/
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    列转行

    把一行当中的列的字段按照行的唯一值转换成多行数据。

    还是上面的栗子,先创建测试表和增加测试数据。

    创建表和增加测试数据

    ------ 列转行前的表创建
    create table XJ_TEST_HL as (
    select 
    t.stuid,
    t.stuname ,
    sum(decode(t.coursename,'数学',t.score,0)) "数学",
    sum(decode(t.coursename,'语文',t.score,0)) "语文",
    sum(decode(t.coursename,'理综',t.score,0)) "理综"
    from XJ_TEST_LtoH t group by t.stuname,t.stuid);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这种语法,就能直接将查询到的数据信息,以及表结构中字段类型等信息,映射成一张新的表。

    此时的数据结构如下所示:
    在这里插入图片描述

    方式一:union all 单个合并

    查询每个需要拆分的列数据信息,以相同的列名接收,再将数据合并。

    -- 方式一:先查询单个,再将所有数据拼接
    select * from (
    select t.stuid,t.stuname,'语文' as coursename,t.语文 as score from XJ_TEST_HL t
    union all
    select t.stuid,t.stuname,'数学' as coursename,t.数学 as score from XJ_TEST_HL t
    union all
    select t.stuid,t.stuname,'理综' as coursename,t.理综 as score from XJ_TEST_HL t
    ) p order by p.stuname;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    方式二:unpivot 函数实现

    语法如下所示:

    select 字段 from 数据集
    
    unpivot(自定义列名/*列的值*/ for 自定义列名 in(列名))
    
    • 1
    • 2
    • 3

    【注意】这里的是 unpivot ,不是 pivot !

    -- 方式二
    -- 语法  select 字段 from 数据集 unpivot(自定义列名/*列的值*/ for 自定义列名 in(列名))
    select * from XJ_TEST_HL
    unpivot (score for coursename in(语文,数学,理综));
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    总结

    pivotunpivot不太好理解,并且属于oracle特有,针对别的类型数据库,可能方式一更好点。

    资料参考

    oracle怎么实现行列转换

  • 相关阅读:
    华为云云耀云服务器L实例评测使用 | 通过程序实现直播流自动分段录制
    Kafka怎样完成建立和Broker之间的连接?
    Spring注解驱动之@Autowired、@Qualifier、@Primary
    安装使用HBuilderx
    十二、stm32-红外遥控(OLED显示)
    七大基于比较的排序算法(JAVA)
    Python selenium基础用法详解
    携程apollo配置中心服务端如何感知配置更新?
    沉睡者 - 现在的百度渠道还有网赚时机吗?
    使用HTTPS模式建立高效爬虫IP服务器详细步骤
  • 原文地址:https://blog.csdn.net/qq_38322527/article/details/127445099