Spark SQL の join はいくつか方法があって、それぞれちょっとずつ挙動が違う。
下記のような DataFrame を2つあったとして
val lowerCase = Seq(
"a",
"b",
"c"
).toDF("lower_case")
val upperCaseMap = Seq(
("a", "A"),
("b", "B"),
("c", "C")
).toDF("lower_case", "lower_case")
===
を使うパターン
lowerCase.join(upperCaseMap, lowerCase("lower_case") === upperCaseMap("lower_case"))
+----------+----------+----------+
|lower_case|lower_case|upper_case|
+----------+----------+----------+
| a| a| A|
| b| b| B|
| c| c| C|
+----------+----------+----------+
それぞれの DataFrame から結合条件に指定した Column を含めて新しく DataFrame を作成する。
重複が嫌な場合は drop(Column)
でカラムを削ってしまうのが良さそう。
lowerCase
.join(upperCaseMap, lowerCase("lower_case") === upperCaseMap("lower_case"))
.drop(upperCaseMap("lower_case"))
+----------+----------+
|lower_case|upper_case|
+----------+----------+
| a| A|
| b| B|
| c| C|
+----------+----------+
Seq(...)
を使うパターン
lowerCase.join(upperCaseMap, Seq("lower_case"))
+----------+----------+
|lower_case|upper_case|
+----------+----------+
| a| A|
| b| B|
| c| C|
+----------+----------+
この場合は Column がマージされる。
結合するときに null も考慮したいとき
前段で紹介した2パターンは null 同士の結合を無視する。
null を含む DataFrame。
val lowerCase = Seq(
"a",
"b",
null
).toDF("lower_case")
val upperCaseMap = Seq(
("a", "A"),
("b", "B"),
(null, "Null")
).toDF("lower_case", "upper_case")
===
を使ったとき。null
の結合は無視される。
lowerCase.join(upperCaseMap, lowerCase("lower_case") === upperCaseMap("lower_case"))
+----------+----------+----------+
|lower_case|lower_case|upper_case|
+----------+----------+----------+
| a| a| A|
| b| b| B|
+----------+----------+----------+
Seq(...)
を使ったとき、null
の結合は無視される。
lowerCase.join(upperCaseMap, Seq("lower_case"))
+----------+----------+
|lower_case|upper_case|
+----------+----------+
| a| A|
| b| B|
+----------+----------+
null の結合をしたい場合は <=>
か .eqNullSafe(...)
を使う
<=>
を使ったとき、null
の結合ができる。
lowerCase.join(upperCaseMap, lowerCase("lower_case") <=> upperCaseMap("lower_case"))
+----------+----------+----------+
|lower_case|lower_case|upper_case|
+----------+----------+----------+
| a| a| A|
| b| b| B|
| null| null| Null|
+----------+----------+----------+
.eqNullSafe(...)
を使っても、null
の結合ができる。
lowerCase.join(upperCaseMap, lowerCase("lower_case").eqNullSafe(upperCaseMap("lower_case")))
+----------+----------+----------+
|lower_case|lower_case|upper_case|
+----------+----------+----------+
| a| a| A|
| b| b| B|
| null| null| Null|
+----------+----------+----------+
その他
外部結合したいとき
第三引数に形式を指定する。デフォルトは inner
。
lowerCase.join(upperCaseMap, lowerCase("lower_case") <=> upperCaseMap("lower_case"), "left")
結合条件を複数指定したいとき
Seq(...)
の場合は必要な分だけ column 名を含めればOK。
他は条件を &&
で繋げばOK。
おわり