为了执行操作或计算,如何参考BigQuery SQL中前几行的列值?

时间:2019-02-15 21:52:00

标签: sql google-bigquery

我已经按照开始时间对数据进行了排序,并且我想创建一个新字段来汇总与上一行开始和结束时间的开始时间重叠的数据。

更具体地说,我想编写一个逻辑,对于给定的记录X,如果开始时间在上一行的开始时间和结束时间之间,我想给记录X赋予与新字段相同的值,上一行。如果开始时间发生在上一行的结束时间之后,它将为新字段获得一个新值。

BigQuery SQL中是否可能出现这种情况?在考虑可能有滞后或窗口功能,但不确定。下面是基本表的外观示例以及我想要最终表的示例。

Original Table

Desired Output Table

任何见识表示赞赏!

2 个答案:

答案 0 :(得分:0)

这是一个空白和孤岛的问题。您要做的是将一个组ID分配给不相交的组。您可以使用窗口函数来计算非交叉点。

如果结束时间的累积最大值(按开始时间排序并在前一条记录处结束)小于当前结束时间,则记录将开始一个新组。剩下的只是分配组ID的累积和。

为您的数据:

select t.*,
       sum(case when prev_endtime >= endtime then 0 else 1 end) over (order by starttime) as group_id
from (select t.*,
             max(endtime) over (order by starttime rows between unbounded preceding and 1 preceding) as prev_endtime
      from t
     ) t;

唯一的潜在问题是两个记录是否恰好同时开始。如果发生这种情况,则逻辑可能需要稍微复杂一些。

答案 1 :(得分:0)

以下是用于BigQuery标准SQL

#standardSQL
SELECT recordID, startTime, endTime,
  COUNTIF(newRange) OVER(ORDER BY startTime) AS newRecordID
FROM (
  SELECT *, 
    startTime >= MAX(endTime) OVER(ORDER BY startTime ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS newRange
  FROM `project.dataset.table`
)

您可以使用问题中的示例数据来测试,玩游戏,如下例所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 recordID, TIME '12:35:00' startTime, TIME '12:50:00' endTime UNION ALL
  SELECT 2, '12:46:00', '12:59:00' UNION ALL
  SELECT 3, '14:27:00', '16:05:00' UNION ALL
  SELECT 4, '15:48:00', '16:35:00' UNION ALL
  SELECT 5, '16:18:00', '17:04:00' 
)
SELECT recordID, startTime, endTime,
  COUNTIF(newRange) OVER(ORDER BY startTime) AS newRecordID
FROM (
  SELECT *, 
    startTime >= MAX(endTime) OVER(ORDER BY startTime ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS newRange
  FROM `project.dataset.table`
)
-- ORDER BY startTime

有结果

Row recordID    startTime   endTime     newRecordID  
1   1           12:35:00    12:50:00    0    
2   2           12:46:00    12:59:00    0    
3   3           14:27:00    16:05:00    1    
4   4           15:48:00    16:35:00    1    
5   5           16:18:00    17:04:00    1