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
使用 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