9、Spark DataFrame理解和使用之两个DataFrame复杂高级的JOIN

复杂高级type的join操作

1、只要能返回布尔型结果(True/False)的判断表达式,都可以作为JOIN的关联表达式

2、关联操作后的结果表中处理重复列名的三种方法

3、spark做JOIN时两个表/DF的通讯机制,三种情况

 

一、只要能返回布尔型结果(True/False)的判断表达式expr,都可以作为JOIN的关联表达式

1、array_contains()函数,两个DF没有两列能使用明确的相等=条件来判断,但是能发现两列有包含的关系

//in scala, 使用array_contains表达式来做两个DF的JOIN操作
import org.apache.spark.sql.functions.expr

df1.withColumnRenamed("id", "personId")\
   .join(df2, expr("array_contains(spark_status, id)")).show()
# in Python
from pyspark.sql.functions import expr

df1.withColumnRenamed("id", "personId")\
   .join(df2, expr("array_contains(spark_status, id)")).show()
-- in SQL
SELECT * FROM
(select id as personId, name, graduate_program, spark_status FROM table1)
INNER JOIN table2 ON array_contains(spark_status, id)

引申:两个表可以使用array_contains函数在实践中的应用是怎样的呢?

比如可以用来做列过滤,再加上与之前的left_semi 一起使用,不仅可以提高关联的执行效率,还不能写UDF来过滤,岂不是很方便。

2、注意不是随便使用函数表达式就可以的,比如使用用来判断>= 或 <=的表达式 就会报失败

3、如果是自定义的UDF表达式呢?能不能成功关联呢?

 

二、关联操作后的结果表中处理重复列名的三种方法

1、什么情况下会产生重复的列名?

(1)两个DataFrame做JOIN操作的时候,使用的是布尔型表达式,但并没有指定要哪个表的该列

  比如,select * from df1 join df2 on df1.col1=df2.col2  ,这时候会把df1 和df2的col1列都选上,就有了重复列。而一般我们会指定 select df1.col1,df2.col2,...这样避免重复的列名。

(2)两个DataFrame做JOIN操作的时候,有些列也具有相同的列名,但你并没有使用它们做关联

     比如,表1和表2都具有列名col1,col2,col3。但你做关联的时候,只使用了 df1.col1=df2.col1,那么结果表中就包含了表1的col2、col3 和表2的col2、col3,他们就具有了重复的列名。

#in python
#使用列表list[](python语言)(scala语言中是seq()序列)这样的方式做JOIN,能避免col1的重复问题,但因为两个DF还含有col2,col3重复的列名,所以还是会有重复
df1.join(df2,["col1"])

#当然,如果关联条件是col1,col2,col3都关联,就不会有列名重复问题了。
df1.join(df2,["col1","col2","col3"])

2、处理重复列名的三种方法

(1)方法一:将JOIN的布尔型表达式换成string或list列表-python语言(sequence序列-scala语言)

#in python
#1、使用string形式做JOIN,如果相同的列名只有关联列col1的时候
df1.join(df2,"col1").select("col1")

#2、使用列表list做JOIN,如果相同的列名有多个,并且都要做关联时
df1.join(df2,["col1","col2","col3"])

 

 

三、spark做JOIN时两个表/DF的通讯机制(大表 和 大表, 大表 和 小表, 小表 和 小表)

1、大表 和 大表,

 

2、大表 和 小表,

 

3、小表 和 小表

 

 

 

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值