如何计算 BigQuery 中列的布尔聚合?

How do you calculate a boolean aggregate over a column in BigQuery?

我有 table 个用户事件,我想将这些事件投影到 带有一些谓词的新列,然后将每个用户的事件聚合在一起 进入一个新的投影,告诉我用户是否曾经有过谓词匹配 对于他们,或者如果他们从未匹配过,等等

在其他语言中,这通常称为 all()any(),您在其中传递 它是一个布尔值列表,它会告诉您它们是否全部匹配,或者是否匹配 至少一场比赛。这相当于在所有布尔值上使用布尔值 AND 值(例如 all 的情况)或对所有布尔值使用布尔值 OR 值(如 any)。

BigQuery 有这个功能吗?我可以使用 maxmin但并不理想。

示例:

select
month(date_time) m,
count(*) as ct,
max(id_is_present),
min(id_is_present),
max(starts_with_one) max_one,
min(starts_with_one) min_one,
from
(
    select
    length(user_id) > 1 id_is_present,
    regexp_match(user_id, r'^1') starts_with_one,
    date_time
    from
    [user_events.2015_02]
)
group by
m

它利用 max(true, false, false) 产生 true 的行为,因此您可以通过在列中搜索值然后构建来实现 anyall那里。

这是我必须依赖的 hack 还是 BigQuery 支持布尔聚合?

是的,BigQuery 有这样的聚合函数,它使用 SQL 它们的标准名称:

EVERY (will do logical and)
SOME (will do logical or)

以防其他人偶然发现,标准 SQL 提供 logical_and()logical_or。所以,代码可以写成:

select month(date_time) as m, count(*) as ct,
       logical_or(id_is_present),
       logical_and(id_is_present),
       logical_or(starts_with_one) as max_one,
       logical_and(starts_with_one) min_one,
from (select length(user_id) > 1 id_is_present,
             regexp_match(user_id, r'^1') starts_with_one,
             date_time
      from [user_events.2015_02]
      ) u
group by m;