Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql,大查询:聚合变量中两个字符串之间的所有条目_Sql_Google Bigquery_String Aggregation - Fatal编程技术网

sql,大查询:聚合变量中两个字符串之间的所有条目

sql,大查询:聚合变量中两个字符串之间的所有条目,sql,google-bigquery,string-aggregation,Sql,Google Bigquery,String Aggregation,我必须在bigQuery中解决这个问题。我的表格中有以下列: event | time _________________|____________________ start | 1 end | 2 random_event_X | 3 start | 4 error_X | 5 error_Y | 6 end | 7 start

我必须在bigQuery中解决这个问题。我的表格中有以下列:

event            | time
_________________|____________________
start            | 1
end              | 2
random_event_X   | 3
start            | 4 
error_X          | 5 
error_Y          | 6
end              | 7
start            | 8
error_F          | 9
start            | 10
random_event_Y   | 11
error_z          | 12
end              | 13
我想,从结束事件记录一切,直到开始出现,然后计数。任何事情都可能发生在开始和结束之间,也可能发生在它之外。有结束就有开始,有开始就不一定有结束

期望输出如下所示:

string_agg                            | count
"start, end"                          |  1
"start, error_X, error_Y, end"        |  1
"start, random_event_Y error_Z, end"  |  1
所以每一个开始和结束之间的一切,如果开始有结束。因此,如果在时间3没有随机事件,则在时间8开始或在时间9出现错误

我无法找到解决方案,也难以理解如何处理这个问题。欢迎提供任何帮助或建议。

SQL表表示无序集-这在大型并行列数据库(如BigQuery)中尤其如此

因此,我必须假设您还有其他列指定排序。如果是这样,您可以使用累积和来标识组,然后进行聚合:

select grp,
       string_agg(event, ',' order by time)
from (select t.*,
             countif(event = 'start') over (order by time) as grp
      from t
     ) t
group by grp
order by min(time);
注意:我还建议您使用array_agg而不是string_agg。数组通常比字符串更容易使用

编辑:

我明白了,你只想结束。在这种情况下,另一个级别的窗口功能:

select grp,
       string_agg(event, ',' order by <ordering col>)
from (select t.*,
             max(case when event = 'end' then time end) over (partition by grp) as max_end_time
      from (select t.*,
                   countif(event = 'start') over (order by <ordering col>) as grp
            from t
           ) t
     ) t
where max_end_time is null or time <= max_end_time
group by grp
order by min(<ordering col>);

下面是BigQuery标准SQL

#standardSQL
SELECT agg_events, COUNT(1) cnt 
FROM (
  SELECT STRING_AGG(event ORDER BY time) agg_events, COUNTIF(event IN ('start', 'end')) flag   
  FROM (
    SELECT *, COUNTIF(event = 'start') OVER(PARTITION BY grp1 ORDER BY time) grp2     
    FROM (
      SELECT *, COUNTIF(event = 'end') OVER(ORDER BY time DESC) grp1 
      FROM `project.dataset.table`
    )
  )
  GROUP BY grp1, grp2
)
WHERE flag = 2
GROUP BY agg_events   
如果要应用于您问题中的样本数据-结果为

Row agg_events                          cnt  
1   start,random_event_Y,error_z,end    1    
2   start,error_X,error_Y,end           1    
3   start,end                           1   

谢谢你的回答。确实有一个排序列,它是一个UNIX时间戳,我将编辑我的问题,以便它包含它。关于建议的查询,它不会记录列的每个开始和结束之间的所有内容。当我应用它时,我有一个输出,比如开始、结束、事件x、事件A、事件B等等。准确地说,开始并不一定就是结束,这让我更难解决这个问题。