BigQuery GROUP_CONCAT和ORDER BY

时间:2015-07-12 13:23:44

标签: sql google-bigquery

我目前正在使用BigQuery和GROUP_CONCAT,它工作得很好。但是,当我尝试像在SQL中那样向GROUP_CONCAT语句添加ORDER BY子句时,我收到错误。

例如,像

这样的东西

SELECT a, GROUP_CONCAT(b ORDER BY c) FROM test GROUP BY a

如果我尝试指定分隔符,也会发生同样的情况。

有关如何处理此事的任何想法?

3 个答案:

答案 0 :(得分:4)

由于BigQuery不支持GROUP_CONCAT函数中的ORDER BY子句,因此可以使用分析窗口函数来实现此功能。在BigQuery中,GROUP_CONCAT的分隔符只是函数的第二个参数。 下面的例子说明了这一点:

select key, first(grouped_value) concat_value from (
select 
  key, 
  group_concat(value, ':') over 
    (partition by key
     order by value asc
     rows between unbounded preceding and unbounded following) 
  grouped_value 
from (
select key, value from
(select 1 as key, 'b' as value),
(select 1 as key, 'c' as value),
(select 1 as key, 'a' as value),
(select 2 as key, 'y' as value),
(select 2 as key, 'x' as value))) group by key

将产生以下内容:

Row key concat_value     
1   1   a:b:c    
2   2   x:y

关于窗口规范的注释:查询使用"行之间的无界前后无界"窗口规范,以确保分区中的所有行都参与GROUP_CONCAT聚合。每个SQL标准默认窗口规范是"无界前行和当前行之间的行"这对于运行总和等问题很有帮助,但在这个问题上却无法正常工作。

性能说明:尽管多次重新计算聚合函数看起来很浪费,但BigQuery优化器确实认识到,由于窗口没有改变,结果将是相同的,因此它只计算每个分区的聚合一次。

答案 1 :(得分:2)

BigQuery中的标准SQL模式支持某些聚合函数中的ORDER BY子句,包括STRING_AGG,例如:

#standardSQL
select string_agg(t.x order by t.y) 
from unnest([struct<x STRING, y INT64>('a', 5), ('b', 1), ('c', 10)]) t

将导致

b,a,c

文档在这里:https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#using-order-by-with-aggregate-functions

答案 2 :(得分:1)

这是BigQuery中标准SQL模式下的版本,其中ARRAY_AGG作为聚合函数:

select key,
array_agg(struct(grouped_value) order by array_length(grouped_value) desc limit 1)[offset(0)].*
from (
select 
  key, 
  array_agg(value) over 
    (partition by key
     order by value asc
     rows between unbounded preceding and unbounded following) 
  grouped_value 
from (
select key, value from unnest([
    struct(1 as key, "b" as value)
  , struct(1, "c")
  , struct(1, "a")
  , struct(2, "y")
  , struct(2, "x")
]))) group by key