Oracle 行列转换(一) case行列转换思路简析

版权声明:本文为原创文章,转载请标明出处。 https://blog.csdn.net/zwjzqqb/article/details/81736182

思路简析:

1° 准备测试数据:

drop table t purge;
create table t(a varchar2(10), b varchar2(10));
insert into t values('a1','b1');
insert into t values('a1','b2');
commit;

2° 进行行列转换的数据一般是”某一列”存在重复冗余的数据,如:

select * from t;

这里写图片描述

表t的列A中值a1存在重复,可以将a1作为基准,对a1所在的两行的列B的数值b1和b2做行列转换,行转列
因为列B的取值范围有两个b1和b2,因此行列转换后会生成两列,即两行转两列

3° 生成新列:

select a, b,
       case b when 'b1' then '第1个列值生成新第1列'
         else null
       end as b1,
       case b when 'b2' then '第2个列值生成新第2列'
         else null
       end as b2
  from t;

这里写图片描述

使用多个case函数对列B的列值进行匹配,将匹配到的相应列值转化成新列,行转列数据模式初显

4° case语法较为臃肿,使用decode函数进行改写:

select a, b,
       decode(b,'b1','第1个列值生成新第1列',null) as b1,
       decode(b,'b2','第2个列值生成新第2列',null) as b2
  from t;

5° 我们已经将B列列值展开成多列,因此剔除B列展示,然后先查看展开生成的第一列,观察特点:

select a, -- b,
       decode(b,'b1','第1个列值生成新第1列',null) as b1 -- ,
       -- decode(b,'b2','第2个列值生成新第2列',null) as b2
  from t;

这里写图片描述

此时不难发现,展开生成的第一列存在空值,意义不大,应该过滤掉,可以使用 where B1 is not null
但是该方法需要使用子查询,因为SQL执行顺序是先执行where后执行select

6° 另外一种方法是依据A列分组,对B1列进行聚合处理,因为B1是字符串,使用max或者min均可过滤掉空值:

select a, -- b,
       min(decode(b,'b1','第1个列值生成新第1列',null)) as b1 -- ,
       -- decode(b,'b2','第2个列值生成新第2列',null) as b2
  from t
  group by a;

这里写图片描述

7° 将所有展开列都依此处理,得出最后SQL:

扫描二维码关注公众号,回复: 3113817 查看本文章
select a, -- b,
       min(decode(b,'b1','第1个列值生成新第1列',null)) as b1,
       max(decode(b,'b2','第2个列值生成新第2列',null)) as b2
  from t
  group by a;

这里写图片描述

8° 简单总结:

字段值重复是行列转换的基础,如果不存在冗余数据列,则无法进行行列转换
行列转换的方法就是使用case或者decode对冗余数据列之外的其他列的列值进行展开
然后依据冗余数据列分组聚合,最后形成行列转换的功能

[TOC]

猜你喜欢

转载自blog.csdn.net/zwjzqqb/article/details/81736182
今日推荐