Scala LEFT JOIN在数据帧上使用两列(不区分大小写)

时间:2017-11-01 13:03:29

标签: scala apache-spark dataframe join apache-spark-sql

我创建了以下方法,该方法需要两个Dataframe; lhs& rhs和它们各自的第一和第二列作为输入。该方法应使用为每个数据帧提供的两列返回这两个帧之间的左连接结果(忽略它们的区分大小写)。

我面临的问题是它正在做更多的内连接。它返回的是lhs数据帧中行数的3倍(由于rhs中的重复值),但由于它是左连接,因此rhs数据帧中的重复和行数无关紧要。

  def leftJoinCaseInsensitive(lhs: DataFrame, rhs: DataFrame, leftTableColumn: String, rightTableColumn: String, leftTableColumn1: String, rightTableColumn1: String): DataFrame = {
    val joined: DataFrame = lhs.join(rhs, upper(lhs.col(leftTableColumn)) === upper(rhs.col(rightTableColumn)) && upper(lhs.col(leftTableColumn1)) === upper(rhs.col(rightTableColumn1)), "left");
    return joined
  }

2 个答案:

答案 0 :(得分:3)

如果rhs中存在重复值,则lhs复制是正常的。如果lhs row的加入列中的加入值与多个rhs rows匹配,则加入dataframe的{​​{1}}中的多个rows应与来自lhs的{​​{1}}匹配rows

例如

rhs

并且

lhs dataframe
+--------+--------+--------+
|col1left|col2left|col3left|
+--------+--------+--------+
|a       |1       |leftside|
+--------+--------+--------+

然后将rhs dataframe +---------+---------+---------+ |col1right|col2right|col3right| +---------+---------+---------+ |a |1 |rightside| |a |1 |rightside| +---------+---------+---------+ left作为

是正常的
join

您可以获得更多信息here

答案 1 :(得分:2)

  

但因为它是一个左连接rhs中的重复和行数   数据框无关紧要

不正确。您的leftJoinCaseInsensitive方法对我来说很好。如果右表有重复的键列,左连接仍会产生比左表更多的行,如下所示:

val dfR = Seq(
  (1, "a", "x"),
  (1, "a", "y"),
  (2, "b", "z")
).toDF("k1", "k2", "val")

val dfL = Seq(
  (1, "a", "u"),
  (2, "b", "v"),
  (3, "c", "w")
).toDF("k1", "k2", "val")

leftJoinCaseInsensitive(dfL, dfR, "k1", "k1", "k2", "k2")

res1.show
+---+---+---+----+----+----+
| k1| k2|val|  k1|  k2| val|
+---+---+---+----+----+----+
|  1|  a|  u|   1|   a|   y|
|  1|  a|  u|   1|   a|   x|
|  2|  b|  v|   2|   b|   z|
|  3|  c|  w|null|null|null|
+---+---+---+----+----+----+