【问题标题】:BigQuery Time String like in Google Analytics H*HH:MM:SSGoogle Analytics 中的 BigQuery 时间字符串 H*HH:MM:SS
【发布时间】:2018-08-23 06:06:33
【问题描述】:

有人想知道如何让 BigQuery 中的这些奇怪的时间字符串看起来像 Google Analytics 中的那些?

它们由 [any amount of hours]:[minutes]:[seconds] 组成,这就是正常时间函数无法真正工作的原因。

例子:

  • 85667:34:02
  • 260:59:34
  • 02:01:01

【问题讨论】:

    标签: google-analytics google-bigquery


    【解决方案1】:

    如果有人找到涉及较少功能的解决方案并将其发布在这里会很酷

    唯一让我(总是)有点头晕的原因是使用CASTs、FLOORs 和MODs

    所以,下面是转换为 ga 格式的更美观(从我的预期)版本

    首先是简单的例子 - 我认为它是不言自明的

    #standardSQL
    WITH `table` AS (
      SELECT 1925 AS seconds  UNION ALL
      SELECT 3600             UNION ALL
      SELECT 86430            UNION ALL
      SELECT 1111111925 
    )
    SELECT seconds, 
      FORMAT('%02d:%s', hours, FORMAT_TIMESTAMP('%M:%S', ts)) as ga_style
    FROM `table`, 
    UNNEST([STRUCT(
      TIMESTAMP_SECONDS(seconds) AS ts, 
      TIMESTAMP_DIFF(TIMESTAMP_SECONDS(seconds), TIMESTAMP_SECONDS(0), HOUR) AS hours
    )])
    

    结果为

    Row       seconds       ga_style     
    1           1,925       00:32:05     
    2           3,600       01:00:00     
    3          86,430       24:00:30     
    4   1,111,111,925   308642:12:05       
    

    最后,下面是用 SQL UDF 包装的逻辑,并应用于与 OP 的答案中相同的脚本

    CREATE TEMP FUNCTION time_str(seconds INT64) AS ((
      SELECT FORMAT('%02d:%s', hours, FORMAT_TIMESTAMP('%M:%S', ts)) 
      FROM UNNEST([STRUCT(
        TIMESTAMP_SECONDS(seconds) AS ts, 
        TIMESTAMP_DIFF(TIMESTAMP_SECONDS(seconds), TIMESTAMP_SECONDS(0), HOUR) AS hours
      )]) 
    ));
    SELECT
      device.browser, 
      time_str(SUM(totals.timeOnSite)) timeOnSite
    FROM `google.com:analytics-bigquery.LondonCycleHelmet.ga_sessions_20130910`
    GROUP BY 1
    ORDER BY SUM(totals.timeOnSite) DESC 
    

    或者更简化:

    CREATE TEMP FUNCTION time_str(seconds INT64) AS (
      FORMAT('%02d:%s', 
        TIMESTAMP_DIFF(TIMESTAMP_SECONDS(seconds), TIMESTAMP_SECONDS(0), HOUR), 
        FORMAT_TIMESTAMP('%M:%S', TIMESTAMP_SECONDS(seconds))
      ) 
    );
    SELECT
      device.browser, 
      time_str(SUM(totals.timeOnSite)) timeOnSite
    FROM `google.com:analytics-bigquery.LondonCycleHelmet.ga_sessions_20130910`
    GROUP BY 1
    ORDER BY SUM(totals.timeOnSite) DESC
    

    结果为

    Row browser          timeOnSite  
    1   Chrome             00:32:05  
    2   Firefox            00:12:40  
    3   Android Browser    00:05:04  
    4   Safari             00:03:28  
    5   Internet Explorer  00:00:26    
    

    注意:尽管我主要关注美学方面 - 同时这个版本有 6 个功能,而原始帖子中有 8 个 - 如果它真的很重要 :o)

    【讨论】:

    • 我喜欢这个解决方案!我从没想过使用时间差异功能......非常酷。然而,当你提到CASTs 和FLOORs 我想解释一下——这让我想:是的,我使用它是因为数字变成了浮点数——但是等等,不是有整数除法吗?是的,有 :D 所以我会优化我的查询。但我认为您的方法可能更具可读性
    【解决方案2】:

    我正在使用一个临时函数(预计秒数)来连接 3 个值:

    • 小时:通过除法/3600和
    • 截断分秒
    • 分:用除法和地板截断秒;用模数截断时间
    • 秒:用模数截断分钟和小时

    所有生成的整数都被格式化为显示两个零。

    示例代码:

    CREATE TEMP FUNCTION time_str(seconds INT64) AS (
      FORMAT("%02d:%02d:%02d",
        DIV(seconds,3600),
        MOD(DIV(seconds,60) , 60),
        MOD(seconds, 60) 
      )
    );
    
    SELECT
      device.browser, 
      time_str(SUM(totals.timeOnSite)) timeOnSite
    FROM
      `google.com:analytics-bigquery.LondonCycleHelmet.ga_sessions_20130910`
    GROUP BY 1
    ORDER BY SUM(totals.timeOnSite) DESC
    

    希望有帮助!

    如果有人找到涉及较少功能的解决方案并将其发布在此处,那就太棒了。

    感谢ElliottMikhail 的提示!

    【讨论】:

    • 一个小的优化:您可以使用对FORMAT 的单个调用和多个参数,对吗? FORMAT("%02d:%02d:%02d", ...)
    猜你喜欢
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多