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 INNOT 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 中工作的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别