【问题标题】:Selecting the first and last event per user, per day每天为每位用户选择第一个和最后一个事件
【发布时间】:2018-08-07 08:30:42
【问题描述】:

我有一个 Google Analytics 事件,当进行某些交互时,它会在我的网站上触发,对于会话中的用户可能会触发也可能不会触发,或者可以触发多次。

我想每天返回显示用户 ID 以及第一个和最后一个事件标签的值的结果。我曾尝试使用 MAX(hits.eventInfo.eventLabel) 来执行此操作,但是当我检查结果时,这并没有像我预期的那样返回该用户当天的最后一个值。

SELECT Date,
customDimension.value AS UserID,
MAX(hits.eventInfo.eventLabel) AS last_value
FROM `project.dataset.ga_sessions_20*` AS t
  CROSS JOIN UNNEST(hits) AS hits
  CROSS JOIN UNNEST(t.customdimensions) AS customDimension
WHERE parse_date('%y%m%d', _table_suffix) between 
DATE_sub(current_date(), interval 1 day) and
DATE_sub(current_date(), interval 1 day)
AND hits.eventInfo.eventAction = "Value"
AND customDimension.index = 2
GROUP BY Date, UserID

例如,上面的查询返回用户 X 具有以下 MAX() 值的结果:

20180806 User_x 69.96

但是当我查看当天用户交互的详细信息时:

基于此,我希望看到 79.95 作为我的 MAX() 结果,因为它具有最高的命中数,而不是我似乎从会话中间的某个地方选择了一个值 - 我该如何调整我的查询以确保我选择了最后一个事件值?

【问题讨论】:

    标签: sql google-bigquery


    【解决方案1】:

    当您在执行 GROUP BY 时寻找列 colA 的最大值时 - 显然 MAX(colA) 会起作用

    但是,当您根据 colB 列中的最大值在 colA 列中查找值时 - 您应该使用 STRING_AGG(colA ORDER BY colB DESC LIMIT 1) 或类似使用 ARRAY_AGG()

    所以,在你的情况下,我认为它会像下面这样(你应该进一步调整)

    STRING_AGG(eventInfo.eventLabel ORDER BY hiNumber DESC LIMIT 1) AS last_value
    

    【讨论】:

      【解决方案2】:

      在您的情况下,应该使用 hits 数组上的子查询。这允许完全控制您想要拥有的内容。我使用了谷歌的示例 ga 数据,所以标签是不同的。但我以一种您可以轻松修改以满足您的需求的方式编写它:

      SELECT
        date,
        fullvisitorid,
        visitstarttime,
        (SELECT value FROM t.customDimensions WHERE index=2) userId,
      
        (SELECT 
            --STRUCT(hour, minute, hitNumber, eventinfo.eventlabel) -- for testing, comment out next line  
            eventInfo.eventLabel 
          FROM t.hits 
          WHERE type='EVENT' AND eventInfo.eventAction <> '' -- modify to fit your condition
          ORDER BY hitNumber ASC LIMIT 1
          ) AS firstEventLabel,
      
        (SELECT
            --STRUCT(hour, minute, hitNumber, eventinfo.eventlabel) -- for testing, comment out next line
            eventInfo.eventLabel 
          FROM t.hits 
          WHERE type='EVENT' AND eventInfo.eventAction <> '' -- modify to fit your condition
          ORDER BY hitNumber DESC LIMIT 1
          ) AS lastEventLabel
      FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_20170801` t
      LIMIT 1000 -- for testing
      

      基本上,我通过 hitNumber 升序或降序来查询事件,并限制为每行只有一个结果。带有 userId 的行还显示了如何正确获取自定义维度值。

      如果您对使用数组这一概念非常陌生,可以在这里了解所有相关信息:https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays

      【讨论】:

        【解决方案3】:

        MAX() 应该可以工作。有一次它会返回一个意外的值是如果它是在一个字符串上操作,而不是一个数字。

        这能解决问题吗?

        MAX(CAST(hits.eventInfo.eventLabel as float128)) AS last_value
        

        【讨论】:

        • 嗨,戈登,转换为浮点数意味着 MAX() 将正确选择最大值,但我希望选择最后一个值,这不一定是最高值,因为值可以上升或在用户访问期间下降。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-23
        • 2021-03-04
        相关资源
        最近更新 更多