NOT IN 不能在 google BigQuery 标准 sql 中工作
Posted
技术标签:
【中文标题】NOT IN 不能在 google BigQuery 标准 sql 中工作【英文标题】:NOT IN not working in google BigQuery standard sql 【发布时间】:2017-01-10 07:24:01 【问题描述】:我正在使用 Google BigQuery,我正在尝试从“table2”中查找“用户 ID”,不包括存储在“table1”中 2 次或更多次的用户 ID。 这是代码:
#standardSQL
WITH t100 AS (
SELECT count_table.userid
From(
SELECT userid,COUNT(`project.dataset.table1`.userid) as notification_count
FROM `project.dataset.table1`
GROUP BY userid) as count_table
where notification_count >= 2
)
SELECT userid FROM `project.dataset.table2` WHERE userid NOT IN (SELECT userid FROM t100)
问题是,这是从 'table1' 返回存储 2 次或更多次的 'userid's,我尝试将 WHERE userid IS NOT NULL
添加到 SELECT userid FROM t100
,但它没有任何区别。
只是为了让一切都更清楚,这个:
SELECT userid FROM t100
, 不为空,并且由于某种原因返回的结果仍然显示在上面第一个代码的结果中。
【问题讨论】:
【参考方案1】:我尝试将 WHERE userid IS NOT NULL 添加到 SELECT userid FROM t100,但没有任何区别
这当然没有影响,因为当您执行 COUNT(userid) as notification_count
时,它总是为用户 ID NULL 返回 0,因此被 HAVING notification_count >= 2
过滤掉了
如果您改用 COUNT(1) - 这就是您可能会在 t100 的输出中获得空用户 ID 的地方。所以userid is NULL
在这里绝对不是问题
正如其他人指出的那样 - 您的查询应该有效 - 因此,如果您继续遇到问题 - 您需要深入挖掘此问题并向我们提供更多详细信息
同时,在下面尝试另一个版本的(否则看起来不错)查询
#standardSQL
WITH t100 AS (
SELECT userid
FROM `project.dataset.table1`
GROUP BY userid
HAVING COUNT(userid) >= 2
)
SELECT userid
FROM `project.dataset.table2` AS t2
LEFT join t100 ON t100.userid = t2.userid
WHERE t100.userid IS NULL
【讨论】:
这行得通,我不知道为什么我的查询不起作用或为什么其他答案包含的查询不起作用。但是谢谢。【参考方案2】:这是由于 null 处理。在我们的issue tracker 上有一个类似的帖子,关于NOT IN
与NOT EXISTS
。 documentation for IN 声明:
IN 列表中带有 NULL 的 IN 只能返回 TRUE 或 NULL,绝不会返回 FALSE
要实现您想要的语义,您应该使用反半联接 (NOT EXISTS
)。例如,
#standardSQL
WITH t100 AS (
SELECT
userid,
COUNT(userid) as notification_count
FROM `project.dataset.table1`
GROUP BY userid
HAVING notification_count >= 2
)
SELECT userid
FROM `project.dataset.table2` AS t2
WHERE NOT EXISTS (SELECT 1 FROM t100 WHERE userid = t2.userid);
【讨论】:
这是我的第一个想法,但 OP 声明:“我尝试将WHERE userid IS NOT NULL
添加到 SELECT userid FROM t100
,但没有任何区别”
该版本的查询中存在其他错误或存在错误,这似乎不太可能。
您可以查看 Mikhail Berlyant 的答案,它出于某种原因有效,我的原始查询和您的答案或第一个都无效,无论如何,谢谢。【参考方案3】:
不知道为什么这不起作用,但出于一般原则,我从不将 (not) in
与 select 语句结合使用。相反,我会left outer join
子查询并过滤其中的空值:
#standardSQL
with t100 as (
select
count_table.userid
from(
select
userid
,count(`project.dataset.table1`.userid) as notification_count
from `project.dataset.table1`
group by
userid
) as count_table
where notification_count >= 2
)
select
t2.userid as userid
from `project.dataset.table2` t2
left outer join t100
on t100.userid = t2.userid
where t100.userid is null
【讨论】:
以上是关于NOT IN 不能在 google BigQuery 标准 sql 中工作的主要内容,如果未能解决你的问题,请参考以下文章