我创建了下面的方法,它接受两个数据帧;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
}
如果 rhs
中有重复的值,那么lhs
被复制是正常的。如果连接列中的连接值与多个rhs rows
匹配lhs row
则连接dataframe
应具有多个rows
,lhs
与rhs
中的rows
匹配。
例如
lhs dataframe
+--------+--------+--------+
|col1left|col2left|col3left|
+--------+--------+--------+
|a |1 |leftside|
+--------+--------+--------+
和
rhs dataframe
+---------+---------+---------+
|col1right|col2right|col3right|
+---------+---------+---------+
|a |1 |rightside|
|a |1 |rightside|
+---------+---------+---------+
那么left
join
是正常的
left joined lhs with rhs
+--------+--------+--------+---------+---------+---------+
|col1left|col2left|col3left|col1right|col2right|col3right|
+--------+--------+--------+---------+---------+---------+
|a |1 |leftside|a |1 |rightside|
|a |1 |leftside|a |1 |rightside|
+--------+--------+--------+---------+---------+---------+
您可以在此处获取更多信息
但由于它是左连接,因此 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|
+---+---+---+----+----+----+