【问题标题】:Window function and time difference in Big QueryBig Query 中的窗口函数和时差
【发布时间】:2016-02-01 18:29:16
【问题描述】:

我有一个大查询表定义为:

+----+----------------+------------+ |编号 |时间 |活动 | +----+----------------+------------+ | 1 | 2015-10-01 16:31:48.000000 |注册 | | 1 | 2015-10-01 16:41:48.000000 | 1_购买 | | 1 | 2015-10-01 16:51:48.000000 | 2_购买 | | 2 | 2015-10-01 16:31:48.000000 |注册 | | 2 | 2015-10-01 16:41:48.000000 | 1_购买 | | 3 | 2015-10-01 16:31:48.000000 |注册 | +----+----------------+------------+

我想计算每个 id 组 (1,2,3) 内的时间差,得到的结果为:

+----+----------------+------------+-- ---------------+---+ |编号 |时间 |活动 |时差 | | +----+----------------+------------+-- ---------------+---+ | 1 | 2015-10-01 16:31:48.000000 |注册 | - | | | 1 | 2015-10-01 16:41:48.000000 | 1_购买 | 00:10:00.000000 | | | 1 | 2015-10-01 16:61:48.000000 | 2_购买 | 00:20:00.000000 | | | 2 | 2015-10-01 16:31:48.000000 |注册 | - | | | 2 | 2015-10-01 16:41:48.000000 | 1_购买 | 00:10:00.000000 | | | 3 | 2015-10-01 16:31:48.000000 |注册 | no_purchase | | +----+----------------+------------+-- ---------------+---+

经过一番研究,我想我需要使用窗口功能......但我想不出任何解决方案。 非常感谢任何帮助! 最好的, 五、

【问题讨论】:

    标签: sql time google-bigquery window-functions


    【解决方案1】:

    是的,您可以为此使用分析窗口函数 - 这是使用 FIRST_VALUE 分析函数的一种方法:

    SELECT id, time, event, (time - firsttime) / 60000000 FROM (
    SELECT id, time, event, 
           FIRST_VALUE(time) OVER(PARTITION BY id ORDER BY time) AS firsttime FROM
    (SELECT 1 id, TIMESTAMP('2015-10-01 16:31:48.000000') time, 'signup' event),
    (SELECT 1 id, TIMESTAMP('2015-10-01 16:41:48.000000') time, '1_purchase' event),
    (SELECT 1 id, TIMESTAMP('2015-10-01 16:51:48.000000') time, '2_purchase' event),
    (SELECT 2 id, TIMESTAMP('2015-10-01 16:31:48.000000') time, 'signup' event),
    (SELECT 2 id, TIMESTAMP('2015-10-01 16:41:48.000000') time, '1_purchase' event),
    (SELECT 3 id, TIMESTAMP('2015-10-01 16:31:48.000000') time, 'signup' event)
    )
    

    【讨论】:

      【解决方案2】:
      select 
        id, time, event, 
        time(sec_to_timestamp((timestamp_to_sec(timestamp(time)) -     
          timestamp_to_sec(timestamp(prev_time))))) as timedifference,
        (timestamp_to_sec(timestamp(time)) -     
          timestamp_to_sec(timestamp(prev_time)))/60 as timefifference_in_min,
      
        right('0' + string(datediff(timestamp(time),timestamp(prev_time))),2) + ' ' +
        time(sec_to_timestamp((timestamp_to_sec(timestamp(time)) -     
          timestamp_to_sec(timestamp(prev_time))))) as timedifference_as_dd_hh_mm_ss
      
      from (
        select 
          id, time, event,
          lag(time) over(partition by id order by time) as prev_time
        from (
        select f0_ as id, f1_ as time, f2_ as event from
          (select 1, '2015-10-01 16:31:48.000000', 'signup'),
          (select 1, '2015-10-01 16:41:48.000000', '1_purchase'),
          (select 1, '2015-10-01 16:51:48.000000', '2_purchase'),
          (select 2, '2015-10-01 16:31:48.000000', 'signup'),
          (select 2, '2015-10-01 16:41:48.000000', '1_purchase'),
          (select 3, '2015-10-01 16:31:48.000000', 'signup')
        )
      )
      order by id, time
      

      【讨论】:

      • 谢谢,还没用过滞后功能:)
      • 但问题是......我只是在几个小时内得到了差异,如果差异超过 1 天,它不会考虑......
      • 您的示例中的时差格式让我认为您不希望 diff 大于 24 小时。看起来情况并非如此,所以我在答案中添加了“timefifference_in_min”。如果您期望/需要某种特定格式 - 请提供示例
      • 在我的回答中添加了 timedifference_as_dd_hh_mm_ss。产生“dd hh:mm:ss”
      • 如果你觉得你得到了你正在寻找的答案 - 你可以投票/接受它:o)
      猜你喜欢
      • 1970-01-01
      • 2016-04-12
      • 2016-04-03
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      相关资源
      最近更新 更多