BigQuery SPLIT() 并按结果分组

BigQuery SPLIT() and grouping by result

使用 SPLIT() & NTH(),我拆分了一个字符串值,并将第二个子字符串作为结果。然后我想根据那个结果分组。但是,当我将 SPLIT() 与 GROUP BY 结合使用时,它一直给出错误:

Error: (L1:55): Cannot group by an aggregate

结果是一个字符串,为什么不能对其进行分组?

例如,这有效 returns 正确的字符串:

SELECT NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] limit 10

但是结果分组不起作用:

SELECT NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] GROUP BY second_part limit 10

我最好的猜测是您可以通过使用子查询获得等效的结果。像 :

SELECT * FROM (Select NTH(2,SPLIT('FIRST-SECOND','-')) as second_part FROM [FOO.bar] limit 10) GROUP BY second_part 

我猜系统returns在内部聚合中排名第N

如果始终只有 2 个值由分隔符分隔,那么更简单的方法是使用 REGEXP_EXTRACT:

SELECT REGEXP_EXTRACT('FIRST-SECOND','-(.*)') as second_part 
from [FOO.bar] 
GROUP BY second_part 
limit 10

我喜欢 David 的回答 - 有时使用 RegEx 拆分会变得更复杂一些。从拆分命令中提取第一个选项,然后进行 GROUPing BY 是非常常见的操作。我通常在 BigQuery 中执行此操作的方式是使用 REGEXP_EXTRACT,如下所示:

在这个简单的示例中,列 "splitme" 是竖线分隔的 (|)。

SELECT REGEXP_EXTRACT(splitme, r'(?U)^(.*)\|') AS title, COUNT(*) as c
FROM [my_table]
GROUP BY title;

这意味着,提取从 "splitme" 开始到管道 (|) 第一次出现的字符串。 “(?U)”是 re2 RegEx 引擎语法中的 "un-greedy" 匹配标志。没有这个标志,如果有多个管道分隔值,这个 RegEx 将匹配所有内容直到最后一个管道。

在我的实践中,我通常使用类似下面的内容,其中 N 是 "list" 中要跳过的值的数量。

SELECT REGEXP_EXTRACT(string + '|',  r'(?U)^(?:.*\|){N}(.*)\|') AS substring 

因此,如果我对列表中的第三个值感兴趣,我会使用:

SELECT 
  REGEXP_EXTRACT(string + '|',  r'(?U)^(?:.*\|){2}(.*)\|') AS substring,
  COUNT(1) AS weight
FROM yourtable
GROUP BY 1

关于 re2 语法的更多细节here