列数未知(pyspark)时如何在多列上联接两个表

时间:2020-09-02 13:53:58

标签: sql join pyspark

假设我有两个表A和B。让它们的结构类似于:

A

------------------------------
col_1 | col_2 | col_3 | col_4
------------------------------
   1  |  A    |  a    |  i
   2  |  B    |  b    |  ii
   3  |  C    |  c    |  iii
   4  |  D    |  d    |  iv
   5  |  E    |  e    |  v
------------------------------

B

---------------
col_1 | col_3 
---------------
  1   |  null
  3   |  c
  null|  b
  2   |  null
--------------

请确保B中的列名称与A中的列名称相同,并且我想在各个列之间使用OR条件连接它们。唯一的问题是B中的列数未知。

如何执行加入?

我想做的伪代码如下:

select *
from A
join B
on A.col_1 == B.col_1
OR A.col_2 == B.col_2
......
OR A.col_k == B.col_k   --where k is the total number of columns in B

我为spark.sql创建了以下字符串,但是我正在寻找一种更Pyspark-ic的方式:

sql_query = 'select s.* from dfA s join dfB on '

#join using or conditions
for i in dfB.columns:
    sql_query += 'dfA.' +i + ' == dfB.' + i + ' OR '

#remove the last extra 'OR'
sql_query = sql_query[:-3]

spark.sql(sql_query)

以上方法要求创建临时视图,以便可以在sqlContext中对其进行访问。

1 个答案:

答案 0 :(得分:1)

Dataframe.columns返回数据框的列列表。通过此属性,我们可以获取两个数据框共有的列:

dfA = ...
dfB = ...

#get the common columns
common_cols = [col for col in dfA.columns if col in dfB.columns]

#create a list of join conditions
join_conds = [dfA[col].eqNullSafe(dfB[col]) for col in common_cols]

#combine all join conditions with "or"
cond = join_conds[0]
for c in join_conds[1:]:
    cond = cond | c

#use the combined condition in a join
dfA.join(dfB, cond).show()