此查询:
SELECT x
FROM dataset.table_a
WHERE x NOT IN (SELECT x FROM dataset.table_b)
即使以下情况,也会返回零记录:
x
中的字段table_a
包含1,326,932个不同的字符串值
x
中的字段table_b
包含18,885个不同的字符串值
我不明白为什么。此外,在BigQuery旧SQL中,此查询返回正确的答案。
答案 0 :(得分:3)
我怀疑我知道答案 - 这是因为使用旧版SQL时NULL
与NOT IN
的处理不正确,而标准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
);
答案 1 :(得分:3)
要尽量减少原始查询中的更改,您只需添加WHERE NOT x IS NULL
,如下所示
#standardSQL
SELECT x
FROM `dataset.table_a`
WHERE x NOT IN (SELECT x FROM `dataset.table_b` WHERE NOT x IS NULL)
另外,我建议如下添加DISTINCT以稍微优化一下
#standardSQL
SELECT x
FROM `dataset.table_a`
WHERE x NOT IN (SELECT DISTINCT x FROM `dataset.table_b` WHERE NOT x IS NULL)