joinのドキュメントを見るとhowのオプションには inner, cross, outer, full, fullouter, full_outer, left, leftouter, left_outer, right, rightouter, right_outer, semi, leftsemi, left_semi, anti, leftanti, left_antiがあるとのことなのでこれの結果を見ていこうと思います。
使用したSparkのバージョンは3.0.1です。
元データ
df0
+----+------+
| id|value0|
+----+------+
| 1| a|
| 2| null|
| 3| c|
| 4| d|
|null| e|
+----+------+
df1
+----+------+
| id|value1|
+----+------+
| 1| A|
| 2| B|
| 3| null|
| 5| null|
| 6| E|
| 7| null|
|null| G|
+----+------+
検証コード
howの部分(この場合はinner)を変えながら検証していきます。
df0 = spark.createDataFrame([
(1, "a"),
(2, None),
(3, "c"),
(4, "d"),
(None, "e")
],
["id", "value0"])
df1 = spark.createDataFrame([
(1, "A"),
(2, "B"),
(3, None),
(5, None),
(6, "E"),
(7, None),
(None, "G")
],
["id", "value1"])
df0.join(df1, "id", "inner").show()
howの種類
ドキュメント上は色々指定できるのですが、この部分を見ると
how | 他バリエーション |
---|---|
fullouter | outer, full, full_outer |
leftouter | left, left_outer |
rightouter | right, right_outer |
leftsemi | semi, left_semi |
leftanti | anti, left_anti |
とのことなのでinner, fullouter, leftouter, rightouter, leftsemi, leftanti, crossを試していきます。
inner
df0、df1をidを基準に結合します。両方に存在する行のみのこります。
SQLだとINNER JOIN
に相当します。
+---+------+------+
| id|value0|value1|
+---+------+------+
| 1| a| A|
| 3| c| null|
| 2| null| B|
+---+------+------+
fullouter
df0、df1両方の行を削らず結合します。
SQLだとFULL OUTER JOIN
に相当します。
+----+------+------+
| id|value0|value1|
+----+------+------+
| 7| null| null|
|null| e| null|
|null| null| G|
| 6| null| E|
| 5| null| null|
| 1| a| A|
| 3| c| null|
| 2| null| B|
| 4| d| null|
+----+------+------+
leftouter
df0を基準にdf1を結合します。
ちなみに、列の順番などは違いますがdf1.join(df0, "id", "rightouter")
とした場合も同じデータが出力されます。
SQLだとLEFT OUTER JOIN
に相当します。
+----+------+------+
| id|value0|value1|
+----+------+------+
|null| e| null|
| 1| a| A|
| 3| c| null|
| 2| null| B|
| 4| d| null|
+----+------+------+
rightouter
df1を基準にdf0を結合します。
ちなみに、列の順番などは違いますがdf1.join(df0, "id", "leftouter")
とした場合も同じデータが出力されます。
SQLだとRIGHT OUTER JOIN
に相当します。
+----+------+------+
| id|value0|value1|
+----+------+------+
| 7| null| null|
|null| null| G|
| 6| null| E|
| 5| null| null|
| 1| a| A|
| 3| c| null|
| 2| null| B|
+----+------+------+
leftsemi
df0にもdf1にもある行を抽出したdf0を返します。
+---+------+
| id|value0|
+---+------+
| 1| a|
| 3| c|
| 2| null|
+---+------+
leftanti
df0にあってdf1に無い行を抽出したdf0を返します。
+----+------+
| id|value0|
+----+------+
|null| e|
| 4| d|
+----+------+
cross
cross
を設定するとUnsupported using join type Cross
という例外が出てしまうので
df0.crossJoin(df1).show()
という様にcrossJoinメソッドを使いました。
※この例外に対してプルリクエストを出したところmasterにマージされたので3.1からはdf0.join(df1, None, "cross")
とすれば使えるようになるはずです。
idに対して全てのコンビネーションの行を返します。
SQLだとCROSS JOIN
に相当します。
+---+------+----+------+
| id|value0| id|value1|
+---+------+----+------+
| 1| a| 1| A|
| 1| a| 2| B|
| 1| a| 3| null|
| 1| a| 5| null|
| 1| a| 6| E|
| 1| a| 7| null|
| 1| a|null| G|
| 2| null| 1| A|
| 2| null| 2| B|
| 2| null| 3| null|
| 2| null| 5| null|
| 2| null| 6| E|
| 2| null| 7| null|
| 2| null|null| G|
| 3| c| 1| A|
| 3| c| 2| B|
| 3| c| 3| null|
| 3| c| 5| null|
| 3| c| 6| E|
| 3| c| 7| null|
+---+------+----+------+