2017-05-04 12 views
4

を返します。BigQueryの標準のSQLクエリは、このクエリを間違った答え

SELECT x 
FROM dataset.table_a 
WHERE x NOT IN (SELECT x FROM dataset.table_b) 

戻りにもかかわらず、レコードをゼロ:table_a

  • フィールドxは1326932明確な文字列が

  • フィールドx値が含まtable_bには18,885の異なる文字列値が含まれています

なぜわかりませんか。さらに、BigQueryの従来のSQLでは、このクエリが正しい答えを返します。

+0

それを最適化するには、以下のようDISTINCT追加することをお勧めしますが、データの一例を与えることができますか?それは埋め込まれていますか? NOT INをINに変更すると、結果はどうなりますか? –

+0

移行ガイドが[従来のSQLと標準SQLの違いを文書化する](https://cloud.google.com/bigquery/docs/reference/standard-sql/migrating-from-legacy-sql#not_in_conditions_and_null)に更新されました。 。 –

答えて

3

私はその答えを知っていると思うが、それはNOT INに関してはNULLの扱いが間違っているからだ。レガシーSQLを使用している場合、標準SQLの動作はSQL標準と一致する。 documentation bug open for this to add it to the migration guideがありますが、まだ解決されていません。

IN(https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#in-operators)のマニュアルに述べて:IN-リストでNULLでINを

はあなたが有する所望の動作を実現することができTRUEまたはNULL、

FALSE決して戻ることができますこのクエリは、代わりにNOT EXISTSを使用して:

SELECT x 
FROM dataset.table_a AS t 
WHERE NOT EXISTS (
    SELECT 1 FROM dataset.table_b 
    WHERE t.x = x 
); 
+0

ありがとうございます。私の考えでは、このルールは次のようになります。 "INリスト内にNULLを入れても、TRUEまたはNULLだけ返します。決して偽ではありません" は論理的に間違っていますか?たとえば、 'aa' IN ['bb'、NULL]は論理的にFALSEを返しますか? – gus87

+0

'aa' = 'bb' OR 'aa' = NULLに相当し、NULLになります。 'SELECT 'aa' = 'bb' OR 'aa' =(SELECT CAST(NULL AS STRING))'を試してください。 –

3

はあなたのoriginalqueryの変化を最小限にするためにあなただけのを追加することができます

#standardSQL 
SELECT x 
FROM `dataset.table_a` 
WHERE x NOT IN (SELECT x FROM `dataset.table_b` WHERE NOT x IS NULL) 

以下のようにはまた、私は少し

#standardSQL 
SELECT x 
FROM `dataset.table_a` 
WHERE x NOT IN (SELECT DISTINCT x FROM `dataset.table_b` WHERE NOT x IS NULL) 
関連する問題