web-dev-qa-db-ja.com

spark SQLで左外部結合を行う方法

spark(1.6.2)で左外部結合を実行しようとしていますが、機能しません。私のSQLクエリは次のようなものです:

sqlContext.sql("select t.type, t.uuid, p.uuid
from symptom_type t LEFT JOIN plugin p 
ON t.uuid = p.uuid 
where t.created_year = 2016 
and p.created_year = 2016").show()

結果は次のようになります。

+--------------------+--------------------+--------------------+
|                type|                uuid|                uuid|
+--------------------+--------------------+--------------------+
|              tained|89759dcc-50c0-490...|89759dcc-50c0-490...|
|             swapper|740cd0d4-53ee-438...|740cd0d4-53ee-438...|

LEFT JOINまたはLEFT OUTER JOINを使用して同じ結果を得ました(2番目のuuidはnullではありません)。

2番目のuuid列はnullのみであると予想されます。左外部結合を正しく行う方法は?

===追加情報==

データフレームを使用して左外部結合を行うと、正しい結果が得られました。

s = sqlCtx.sql('select * from symptom_type where created_year = 2016')
p = sqlCtx.sql('select * from plugin where created_year = 2016')

s.join(p, s.uuid == p.uuid, 'left_outer')
.select(s.type, s.uuid.alias('s_uuid'), 
        p.uuid.alias('p_uuid'), s.created_date, p.created_year, p.created_month).show()

私はこのような結果を得ました:

+-------------------+--------------------+-----------------+--------------------+------------+-------------+
|               type|              s_uuid|           p_uuid|        created_date|created_year|created_month|
+-------------------+--------------------+-----------------+--------------------+------------+-------------+
|             tained|6d688688-96a4-341...|             null|2016-01-28 00:27:...|        null|         null|
|             tained|6d688688-96a4-341...|             null|2016-01-28 00:27:...|        null|         null|
|             tained|6d688688-96a4-341...|             null|2016-01-28 00:27:...|        null|         null|

おかげで、

21
Sean Nguyen

コードに問題は見当たりません。 「左結合」または「左外部結合」の両方が正常に機能します。表示しているデータが一致するデータであることをもう一度確認してください。

次を使用してSpark SQL結合を実行することもできます。

//明示的な左外部結合

df1.join(df2, df1("col1") === df2("col1"), "left_outer")
32
Arvind Kumar

p.created_year(およびp.uuid)のnull値をフィルターで除外しています

where t.created_year = 2016 
and p.created_year = 2016

これを回避する方法は、pのフィルタリング句をONステートメントに移動することです。

sqlContext.sql("select t.type, t.uuid, p.uuid
from symptom_type t LEFT JOIN plugin p 
ON t.uuid = p.uuid 
and p.created_year = 2016
where t.created_year = 2016").show()

これは正しいですが、結合が発生する前にt.created_yearでフィルタリングする必要があるため、非効率的です。したがって、サブクエリを使用することをお勧めします。

sqlContext.sql("select t.type, t.uuid, p.uuid
from (
  SELECT type, uuid FROM symptom_type WHERE created_year = 2016 
) t LEFT JOIN (
  SELECT uuid FROM plugin WHERE created_year = 2016
) p 
ON t.uuid = p.uuid").show()    
4
Ivan Medvedev

あなたはあなたが望むもののためにLEFT OUTER JOINキーワードの代わりにLEFT JOINを使用する必要があると思います。詳細については、 Spark documentation をご覧ください。

2
beljul