Spark 列转行操作

前言

在MySQL和oracle中有列转行函数用于将列转成行。在大数据SQL中也有类似的操作。这里主要讲解Spark的列转行操作。

欢迎关注微信公众号:大数据报文

concat:多列合并

在介绍列转行之前首先要说一下concat函数,为后面列转行做一下铺垫:

 -- mysql:可以一到合并多个值,无法使用分隔符,如果合并的值中有null,则合并的结果为null
 select concat('11','22',null);
 --mysql:可以合并多个值,第一个参数是分隔符。如果有null则忽略null合并其他值
 select concat_ws(',','11','22',null);
 ​
 --oracle:只能连接两个字符串,如果有一个是null,则结果是非null的值
 select concat('111',null) from dual;
Spark的concat函数:
 --spark sql:与mysql的规则相同
 orclDF.select(concat($"CERT_NO", lit(null))).show()

concat_ws:单列转行

RDBMS SQL

 -- mysql:有null值忽略,加distinct参数可以在列转行之前去重
 select name,group_concat(age) from student group by name;
 select name,group_concat(DISTINCT age) from student group by name;--去重
 select id,group_concat(name separator ';') from aa group by id;--以逗号分割
 select id,group_concat(name order by name desc) from aa group by id;--按合并字段排序
 ​
 -- Oracle:合并多列默认以逗号分隔
 select ci_id,wm_concat(stu_name) nameslist from student group by ci_id;
 --将两列合并为一列再列转行
 select ci_id,wm_concat(stu_name || '-' || stu_age) nameslist from student group by ci_id;

 Spark SQL

//spark sql:要稍微复杂一点,要使用多个函数配合
//首先分组以后,肯定是要用聚合函数的,sparksql列转行的算子叫concat_ws,第一个参数是分隔符,如果不需要刻意写空字符串,但是必须指定。第二个参数分组之后dept列的列表。如果是collect_set,表示集合,即后者表示对组内的值去重
 orclDF.select($"id", $"dept", $"dest").groupBy($"id").agg(concat_ws("&", collect_list("dept"))
//通过上面这种方式可以达到上面RDBMS SQL的效果,但是如果合并两列就有些麻烦了,他没有合适的连接符
//下面这种方式,先合并了col1,再合并col2,如果要(col1[1]+col2[1])(col1[2]+col2[2])去合并需要使用concat函数
 orclDF.select($"id", $"dept", $"dest").groupBy($"id").agg(concat_ws("&", collect_list("col1"),collect_list("col2"))    
 -- 下面这种方式是先将两列(应该说三列)合并为一列再列转行
 orclDF.select($"id", $"date", concat($"dept", lit("|"), $"dest").as("track"))
                 .groupBy($"id")
                 .agg(concat_ws(",", collect_list("track")).as("tracks"))
//上面也可以这样写
val testDF = orclDF.select($"id", $"name", $"score1", $"score2")
                .groupBy($"id")
                .agg(concat_ws(";", collect_list(concat($"score1",lit(","),$"score2"))).as("scores"))

总结

Spark SQL的列转行稍微有些复杂,但是逻辑很清晰,本质上还是与传统列转行一样,只是通过这种半编程方式实现起来相对而言稍显复杂。

另外最近复习Spark的一点感触。Spark SQL虽然不是传统sql,但是已经十分接近传统SQL的功能了,绝大多数传统SQL,Spark SQL都有实现。而且DataSet拥有类RDD编程的便利,可以说某些方面Spark SQL要比传统SQL灵活很多。


 ​

你可能感兴趣的:(Spark,列转行,spark,spark,sql)