【问题标题】:How to transform a BigQuery table into a list of row sequences where sequences are aggregated by a sliding window in time?如何将 BigQuery 表转换为行序列列表,其中序列由滑动窗口及时聚合?
【发布时间】:2019-11-04 21:20:57
【问题描述】:

我有一个非常大的表,其中每一行代表一个称为 Trip 的抽象。行程由数字列组成,例如车辆 ID、行程 ID、开始时间、停止时间、行驶距离、行驶时长等。

我想将此表转换为行程序列列表,其中行程按车辆 ID 和时间滑动窗口分组为序列。从本质上讲,每个组/序列都包含来自同一车辆 ID 的行程,其中行程在 5 天的窗口内。自然,组/序列将具有可变长度(最好具有可以忽略额外行程的最大大小)。然而,该窗口是不重叠的,因此旅行不能在两个不同的组/序列中。最后,序列按 StartTime 排序。

示例: (窗口 = 5 天)

[
 **Oct31 - Nov4**
(Vehicle1, [Trip7, Trip8, Trip9, Trip10]),
(Vehicle2, [Trip3, Trip4, Trip5]) 
 **Oct26 - Oct30**
(Vehicle1, [Trip1, Trip2, Trip3, Trip4, Trip5, Trip6]),   
(Vehicle2, [Trip1, Trip2]),
]

以前question的变体

【问题讨论】:

  • 这些时间窗口是如何定义的?他们的逻辑是什么?预定义?飞行?等等
  • 窗口只是一个预定义的常量,比如 5 天
  • 想澄清一下 - 5 天只是一个长度 - 但窗口本身 - 例如,它们是在其他表格中预定义的窗口吗?或者是否有计算这 5 天窗口的开始日期等。
  • 一个开始日期和时间向前滑动是完美的
  • 不清楚(至少对我来说) - 你应该详细说明,也许提供一些数据示例来说明窗口是如何定义的

标签: sql google-bigquery


【解决方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
WITH windows AS (
  SELECT start_day, DATE_ADD(start_day, INTERVAL 4 DAY) end_day
  FROM UNNEST(GENERATE_DATE_ARRAY('2019-10-01', CURRENT_DATE(), INTERVAL 5 DAY)) start_day
)
SELECT start_day, end_day, trip.vehicle_id, ARRAY_AGG(trip ORDER BY trip.start_time) trips
FROM `project.dataset.table` trip
JOIN windows ON start_time BETWEEN start_day AND end_day
GROUP BY start_day, end_day, vehicle_id

您可以使用虚拟数据进行测试,使用上面的示例,如下例所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'Vehicle1' vehicle_id, 'Trip1' trip_id, DATE '2019-10-29' start_time, DATE '2019-10-30' stop_time UNION ALL
  SELECT 'Vehicle1', 'Trip2', '2019-10-30', '2019-10-31' UNION ALL
  SELECT 'Vehicle1', 'Trip3', '2019-10-31', '2019-11-01' UNION ALL
  SELECT 'Vehicle1', 'Trip4', '2019-11-01', '2019-11-02' UNION ALL
  SELECT 'Vehicle1', 'Trip5', '2019-11-02', '2019-11-03' UNION ALL
  SELECT 'Vehicle1', 'Trip6', '2019-11-03', '2019-12-04' UNION ALL
  SELECT 'Vehicle1', 'Trip7', '2019-11-04', '2019-12-05' UNION ALL
  SELECT 'Vehicle2', 'Trip1', '2019-10-29', '2019-10-30' UNION ALL
  SELECT 'Vehicle2', 'Trip2', '2019-10-30', '2019-10-31' UNION ALL
  SELECT 'Vehicle2', 'Trip3', '2019-10-31', '2019-11-01' UNION ALL
  SELECT 'Vehicle2', 'Trip4', '2019-11-01', '2019-11-02'  
), windows AS (
  SELECT start_day, DATE_ADD(start_day, INTERVAL 4 DAY) end_day
  FROM UNNEST(GENERATE_DATE_ARRAY('2019-10-01', CURRENT_DATE(), INTERVAL 5 DAY)) start_day
)
SELECT start_day, end_day, trip.vehicle_id, ARRAY_AGG(trip ORDER BY trip.start_time) trips
FROM `project.dataset.table` trip
JOIN windows ON start_time BETWEEN start_day AND end_day
GROUP BY start_day, end_day, vehicle_id
-- ORDER BY start_day, end_day, vehicle_id

结果

【讨论】:

  • 太棒了,非常感谢你的帮助 Mikhail :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 2013-06-07
相关资源
最近更新 更多