Flink SQL 如何实现列转行 ?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flink SQL 如何实现列转行 ?相关的知识,希望对你有一定的参考价值。
参考技术A 在 SQL 任务里面经常会遇到一列转多行的需求,下面就来总结一下在 Flink SQL 里面如何实现列转行的,先来看下面的一个具体案例.原始数据格式如下:
现在希望得到的数据格式是这样的:
这是一个典型的列转行或者一行转多行的场景,需要将 data 列进行拆分成为多行多列,下面介绍两种实现方式.
这里在定义 data 字段类型的时候直接定义为 ARRAY 类型,因为 unnest 函数需要一个数组类型的参数.
自定义表值函数(UDTF),自定义表值函数,将 0 个、1 个或多个标量值作为输入参数(可以是变长参数)。与自定义的标量函数类似,但与标量函数不同。表值函数可以返回任意数量的行作为输出,而不仅是 1 个值。返回的行可以由 1 个或多个列组成。调用一次函数输出多行或多列数据。必须继承 TableFunction 基类,并实现一个或者多个名为 eval 的方法, 在使用 UDTF 时,需要带上 LATERAL TABLE两个关键字.
自定义 UDTF 解析的时候,就不需要把 data 字段定义成 ARRAY 类型了,直接定义成 STRING 类型就可以了,并且这种方式会更加的灵活,比如还需要过滤数据或者更复杂的一些操作时都可以在 UDTF 里面完成.
unnest 和 自定义 UDTF 函数在使用的时候都有 3 种写法,前面两种写法的效果其实是一样的,第三种写法相当于 left join 的用法.区别在于 CROSS JOIN/INNER JOIN: 对于左侧表的每一行,右侧 UDTF 不输出,则这一行不输出.LEFT JOIN: 对于左侧表的每一行,右侧 UDTF 不输出,则这一行会输出,右侧 UDTF 字段为 null
在实际使用的时候如果 unnest 可以满足需求就直接用 unnest 不需要带来额外的开发,如果 unnest 函数满足不了需求,那么就自定义 UDTF 去完成.
oracle 列转行
有两张表
A 产品表
产品名称,产品编码
产品1 001
B销量表
产品编号 月份 销量
001 1 1000
001 2 2000
001 3 3000
。。。。。。
001 12 12000
通过sql语句如何输出
产品名称 产品编号 1月 2月 3月 。。。。。12月
产品1 001 1000 2000 3000 。。。。 12000
最后请教一个设计表的问题。想这种情况是如上表结构比较好呢?还是将B表设计为
产品编号 1月 2月 3月 。。。。。12月
create or replace procedure ptest as
strname varchar2(30);
str varchar2(1000);
strid varchar2(10);
cursor cur is select * from AB;
begin
str:='';
open cur;
loop
fetch cur into strid,strname;
exit when cur%notfound;
str:=str||strname||',';
end loop;
str:=substr(str,1,length(str)-1);
dbms_output.put_line(str);
end; 参考技术A 基本思路是运用case when语句,最好把创建表的语句给出(可用dbms_metadata.get_ddl,运行前把long设置大点)。
自己利用示例表得出需求,可以根据你自己的表来进行修改:
demo@ORCL>select max(case when deptno=10 then ename else null end) as "部门10",
max(case when deptno=20 then ename else null end) as "部门20",
max(case when deptno=30 then ename else null end) as "部门30"
from
(select deptno,ename,row_number() over(partition by deptno order by ename) rn from emp) x
group by rn order by 1,2,3;
部门10 部门20 部门30
---------- ---------- ---------
CLARK ADAMS ALLEN
KING FORD BLAKE
MILLER JONES JAMES
SCOTT MARTIN
SMITH TURNER
WARD 参考技术B oracle下可以用函数decode处理:
select t1.产品名称,t1.产品编号,
sum(decode(t2.月份,1,t2.销量,0)) 1月,
sum(decode(t2.月份,2,t2.销量,0)) 2月,
sum(decode(t2.月份,3,t2.销量,0)) 3月,
sum(decode(t2.月份,4,t2.销量,0)) 4月,
...
sum(decode(t2.月份,11,t2.销量,0)) 11月,
sum(decode(t2.月份,12,t2.销量,0)) 12月
from 产品表 t1, 销量表 t2
where t1.产品编码=t2.产品编码
group by t1.产品名称,t1.产品编号;
一般设计成你现有这样的结构就可以了.因为销量表是个明细记录表,记录数比较大. 参考技术C select a.产品名称,b.产品编码, wmsys.wm_concat(销量) from 产品表 a, 销量表 b where a.产品编号 = b.产品编码 group by a.产品名称 ,b.产品编码
以上是关于Flink SQL 如何实现列转行 ?的主要内容,如果未能解决你的问题,请参考以下文章