おそらくバグを提出する前にここに提示する。私はSpark 1.6.0を使用しています。スパーク結合が間違った結果をもたらす
これは私が扱っている問題の簡略化されたバージョンです。私はテーブルをフィルタリングして、そのサブセットとメインテーブルで左外部結合を行い、すべての列に一致させようとしています。
私はメインテーブルとフィルタリングされたテーブルに2つの行しか持っていません。私は結果のテーブルがサブセットからの単一の行だけを持つことを期待しています。
scala> val b = Seq(("a", "b", 1), ("a", "b", 2)).toDF("a", "b", "c")
b: org.apache.spark.sql.DataFrame = [a: string, b: string, c: int]
scala> val a = b.where("c = 1").withColumnRenamed("a", "filta").withColumnRenamed("b", "filtb")
a: org.apache.spark.sql.DataFrame = [filta: string, filtb: string, c: int]
scala> a.join(b, $"filta" <=> $"a" and $"filtb" <=> $"b" and a("c") <=> b("c"), "left_outer").show
+-----+-----+---+---+---+---+
|filta|filtb| c| a| b| c|
+-----+-----+---+---+---+---+
| a| b| 1| a| b| 1|
| a| b| 1| a| b| 2|
+-----+-----+---+---+---+---+
私はその結果がまったく期待できませんでした。私は第1列を期待したが、第2列は期待しなかった。私はそれがnull安全な平等だと思ったので、私はそれを試してみました。
scala> a.join(b, $"filta" === $"a" and $"filtb" === $"b" and a("c") === b("c"), "left_outer").show
16/03/21 12:50:00 WARN Column: Constructing trivially true equals predicate, 'c#18232 = c#18232'. Perhaps you need to use aliases.
+-----+-----+---+---+---+---+
|filta|filtb| c| a| b| c|
+-----+-----+---+---+---+---+
| a| b| 1| a| b| 1|
+-----+-----+---+---+---+---+
OK、これは私が期待した結果ですが、警告が表示されないことがあります。ここにその警告に対処する別のStackOverflow質問があります:Spark SQL performing carthesian join instead of inner join
したがって、警告を回避する新しい列を作成します。
scala> a.withColumn("newc", $"c").join(b, $"filta" === $"a" and $"filtb" === $"b" and $"newc" === b("c"), "left_outer").show
+-----+-----+---+----+---+---+---+
|filta|filtb| c|newc| a| b| c|
+-----+-----+---+----+---+---+---+
| a| b| 1| 1| a| b| 1|
| a| b| 1| 1| a| b| 2|
+-----+-----+---+----+---+---+---+
しかし、ここでも結果は間違っています。 私はヌルに安全な平等チェックをたくさんしています。警告は致命的ではありません。だから私はこれを扱う明確な道筋は見当たりません。
この動作はバグですか?これは予期された動作ですか?期待されるならば、なぜですか?
Nullセーフな等価性の実装がないため(実際にはこれが欲しい)、私は結合を使用しませんでした。 null安全なエイリアスバージョンは、より重い構文でも回避策のようです。 問題のバグを報告します。 – kanielc
あなたはJIRAリンクを使って私にpingを実行できますか? – zero323
ここで作成したJira:https://issues.apache.org/jira/browse/SPARK-14040 – kanielc