Oracle行列转换-进阶
准备
多行(按季度)
1 | create table t_fruit_row |
多列(按季度)
1 | create table t_fruit_column |
多行转换成字符串
wm_concat函数
效果1:默认逗号分隔
1 | select t.name, to_char(wm_concat(t.quarter)) from t_fruit_row t group by t.name; |
效果2:把结果里的逗号替换成 “|”
1 | select t.name, replace(to_char(wm_concat(t.quarter)), ',', '|') |
多列转换成字符串
1 | select concat(concat(t.id, t.name), t.quarter) from t_fruit_row t; |
字符串转换成多行
union all
字符串转换成多列
实际上就是字符串拆分问题,可以使用 substr、instr、regexp_substr、regexp_instr 结合 decode、case when 函数。
regexp_substr
1
2
3
4
5 -- 找出匹配的数字
select regexp_substr('hello my phone is 520 ', '[0-9]+') from dual;
-- 返回第三个字符串
select regexp_substr('i like china spa', '(\S*)(\s)', 1, 3) from dual;
行转列
decode+wm_concat
1 | select t.name, |
pivot(行转列)
1 | SELECT ... |
按照序号编写好理解
3、 pivot_clause:指定聚合函数,对值进行聚合。允许指定多个,决定转换后列的倍数。
1、 pivot_for_clause:指定行转列的字段,允许指定多字段。
2、 pivot_in_clause:对 pivot_for_clause 指定的字段进行过滤,只将满足条件的行转成列。可以是固定值、any、子查询(未测试成功)。
转换后的列数 = pivot_clause * pivot_in_clause
1 | -- 单字段转列 |
统计各季度的总销量和该季度最大销量:行转多列
1 | select * |
按照oracle的文档,pivot语句中in后面的列如果不固定,只能使用xml格式的返回结果
1 | -- 单统计列 |
列转行
union all
1 | select t.name, t.year, 'Q1' as quarter, t.Q1 as sales from t_fruit_column t |
unpivot(列转行)
1 | SELECT ... |
INCLUDE NULLS:保留null数据;
EXCLUDE NULLS(默认):不保留null数据。
按照序号编写好理解
3、 unpivot_clause:指定原列值对应的新字段名。
2、 unpivot_for_clause:指定列转行后的字段名,允许多个。
1、 unpivot_in_clause:指定具体列到行的字段名。
1 | select * |
懒人扩展用法
**案例:**现在要写一个视图,类似 create or replace view as select 字段1,...字段50 from tablename
,基表有50多个字段,要是靠手工写太麻烦了,有没有什么简便的方法?应用 wm_concat
来让这个需求变简单,如下:
1 | -- 这里的表名默认区分大小写 |