web-dev-qa-db-ja.com

'NOTEXISTS'のHiveLEFT SEMI JOIN

1つのキー列を持つ2つのテーブルがあります。テーブルaのキーは、テーブルbのすべてのキーのサブセットです。テーブルaにないキーをテーブルbから選択する必要があります。

Hiveマニュアルからの引用は次のとおりです。「LEFTSEMIJOINは、相関のないIN/EXISTSサブクエリセマンティクスを効率的な方法で実装します。Hive0.13以降、IN/NOT IN/EXISTS/NOT EXISTS演算子はサブクエリを使用してサポートされるため、これらのJOINのほとんどはもう手動で実行する必要はありません。LEFTSEMI JOINを使用する場合の制限は、右側のテーブルは結合条件(ON句)でのみ参照され、WHERE-またはSELECTでは参照されないことです。 -句など "

彼らは説明のためにこの例を使用します:

    SELECT a.key, a.value FROM a WHERE a.key IN (SELECT b.key FROM B);

と同等です

    SELECT a.key, a.val FROM a LEFT SEMI JOIN b ON (a.key = b.key);

ただし、私がする必要があるのは、 'NOT IN;を使用した最初の例です。残念ながら、この構文はHive 0.13ではサポートされていません。説明のみを目的としています。

    SELECT a.key, a.value FROM a WHERE a.key NOT IN (SELECT b.key FROM B);

私は推奨事項をこのサイトで検索し、この例を見ました:

    SELECT a.key FROM a LEFT OUTER JOIN b ON a.key = b.key WHERE b.key IS NULL;

期待どおりに動作しません。 a.key NOT bとa.key IN bに参加すると、この方法で元のaを取得できません。おそらく、このクエリではうまくいかないためです。太字のテキストに注意してください。b.keyはWHEREに表示しないでください。

それならどうすればいいですか?他のトリックはありますか?ありがとう!

P.S.実際のデータを共有することはできません。これは非常に単純な例であり、aのキーはすべてbに含まれ、aはbのサブセットです。

11
mel

テーブルbの結果が必要な場合は、代わりに次のようにできますか?

  SELECT b.key FROM b LEFT OUTER JOIN a ON b.key = a.key WHERE a.key IS NULL;
6
okkar

あなたの問題への答えは

SELECT a.key FROM a LEFT OUTER JOIN b ON a.key = b.key WHERE b.key IS NULL;

つまり、bに一致があるかどうかに関係なく、aからすべてのキーを取得します。 where causeは、bでは使用できないレコードをフィルタリングします。

3

または、試すことができます

SELECT a.key FROM a LEFT ANTI JOIN b ON a.key = b.key
3
user3512680

spark 1.6バージョンでcdh 5.7.0のIN関数に左セミジョインを試みました。

半左結合は誤った結果を返します。これは、サブクエリのIN functionとは異なります。

1
j pavan kumar