Google bigquery 如何使用BigQuery获得时间范围重叠的持续时间(以分钟为单位)?

Google bigquery 如何使用BigQuery获得时间范围重叠的持续时间(以分钟为单位)?,google-bigquery,Google Bigquery,我在BigQuery中有一个表,其中包含事件的设备ID、事件类型、开始时间和结束时间。 我需要计算设备活动的总持续时间,注意重叠的时间范围 我可以在每个设备上获取每个事件的时差,但不知道如何获取实际持续时间 WITH sessions as (SELECT 1222 device, 1 event_type, DATETIME(2021,02,02,10,00,00) start_time, DATETIME(2021,02,02,10,10,00) end_time UNION ALL SE

我在BigQuery中有一个表,其中包含事件的
设备
ID、
事件类型
开始时间
结束时间
。 我需要计算设备活动的总持续时间,注意重叠的时间范围 我可以在每个设备上获取每个事件的时差,但不知道如何获取实际持续时间

WITH sessions as (SELECT 1222 device, 1 event_type, DATETIME(2021,02,02,10,00,00) start_time, DATETIME(2021,02,02,10,10,00) end_time
UNION ALL 
SELECT 1222 , 2 , DATETIME(2021,02,02,10,05,00) , DATETIME(2021,02,02,11,00,00) 
UNION ALL 
SELECT 1222 , 1 , DATETIME(2021,02,02,10,20,00) , DATETIME(2021,02,02,10,30,00) 
UNION ALL
SELECT 1333 , 1 , DATETIME(2021,02,02,11,00,00) , DATETIME(2021,02,02,11,30,00) 
UNION ALL 
SELECT 1333 , 2 , DATETIME(2021,02,02,11,35,00) , DATETIME(2021,02,02,11,40,00) 
UNION ALL 
SELECT 1333 , 1 , DATETIME(2021,02,02,11,50,00) , DATETIME(2021,02,02,11,55,00) )
SELECT device, event_type ,start_time ,end_time, DATETIME_DIFF(end_time, start_time ,MINUTE ) FROM sessions

对于每一行,我们可以查看前一行的
结束时间。如果它大于当前行的
start\u time
,那么我们可以使用它来计算持续时间。某些持续时间将为负,因为前一行的
结束时间
可能大于当前行的
结束时间
,因此我们总结所有正持续时间

WITH sessions AS (
  SELECT 1222 device, 1 event_type, DATETIME(2021,02,02,10,00,00) start_time, DATETIME(2021,02,02,10,10,00) end_time UNION ALL 
  SELECT 1222 , 2 , DATETIME(2021,02,02,10,05,00) , DATETIME(2021,02,02,11,00,00) UNION ALL 
  SELECT 1222 , 1 , DATETIME(2021,02,02,10,20,00) , DATETIME(2021,02,02,10,30,00) UNION ALL 
  SELECT 1333 , 1 , DATETIME(2021,02,02,11,00,00) , DATETIME(2021,02,02,11,30,00) UNION ALL 
  SELECT 1333 , 2 , DATETIME(2021,02,02,11,35,00) , DATETIME(2021,02,02,11,40,00) UNION ALL 
  SELECT 1333 , 1 , DATETIME(2021,02,02,11,50,00) , DATETIME(2021,02,02,11,55,00) 
),
calculated_duration AS (
  SELECT 
    *,
    DATETIME_DIFF(
      end_time,
      IFNULL(
        GREATEST(
          start_time,
          LAG(end_time) OVER(PARTITION BY device ORDER BY start_time)
        ),
        start_time
      ),
      MINUTE
    ) AS duration
  FROM sessions
)
SELECT device, SUM(GREATEST(duration, 0))
FROM calculated_duration
GROUP BY device
考虑以下选项

select device, sum(datetime_diff(end_time, start_time ,minute)) duration                   
from (
  select device, time_range, min(start_time) start_time ,max(end_time) end_time, 
  from (
    select device, start_time, end_time,
      countif(new_range) over(partition by device order by start_time) time_range
    from (
      select device, event_type ,start_time ,end_time, 
        ifnull(start_time >= lag(end_time) over(partition by device order by start_time), true) new_range
      from sessions
    )
  )
  group by device, time_range
)
group by device
如果应用于问题中的样本数据,则输出为