【问题标题】:Rolling active users that were also active in previous days in bigquery在 bigquery 中滚动在前几天也很活跃的活跃用户
【发布时间】:2019-08-30 14:11:35
【问题描述】:

我想计算在过去 y 天内活跃 x 次或多次的活跃用户的滚动数量。为简单起见,假设在 5 天内 > 3 次

我拥有的数据是形式

|    date   | user_id   |
------------------
|2019-01-01 | user1     |
|2019-01-01 | user2     |
|2019-01-01 | user1     |
|2019-01-02 | user1     |
|2019-01-02 | user3     |
|2019-01-02 | user4     |
|2019-01-03 | user2     |
|2019-01-03 | user3     |

我尝试使用聚合函数按日期对 user_id 进行分组,并使用窗口函数对前 5 行中存在 >3 次的用户求和。 按日期聚合用户可以使用:

SELECT date, ARRAY_AGG(distinct user_id) as users
FROM `table` 
WHERE date > DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY date

像这样返回一个数组结构。

|    date   | users     |
------------------
|2019-01-01 | user1     |
|           | user2     |
|2019-01-02 | user1     |
|           | user3     |
|           | user4     |
|2019-01-03 | user2     |
|           | user3     |

但我在这里卡住了。我可以做这样的事情吗?但是我应该使用什么分析函数呢?

WITH activity as (
  SELECT date, ARRAY_AGG(distinct user_id) as users
  FROM `table` 
  WHERE date > DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
  GROUP BY date
)

SELECT date, xxxx OVER (PARTITION BY date ORDER BY date ROWS 5 PRECEDING) as returning_users
FROM activity

我想要的输出是:

|    date   | returning_users  |
------------------
|2019-01-01 | 123              |
|2019-01-02 | 1234             |
|2019-01-03 | 12345            |

【问题讨论】:

    标签: google-bigquery window-functions


    【解决方案1】:

    您可能是对的,有一些合适的窗口函数可以实现这一点,但如果有的话,我并不熟悉。

    但是由于没有现成的解决方案,这里是一个只使用连接的工作方法:

    WITH ACTIVE_DAYS AS (
      SELECT
        a.date,
        a.user_id,
        COUNT(DISTINCT b.date) AS ActiveDays
      FROM
        DATA a
      JOIN
        DATA b
      ON
        a.user_id = b.user_id
        AND b.date BETWEEN DATE_SUB(a.date, INTERVAL 5 DAY) AND DATE_SUB(a.date, INTERVAL 1 DAY)
      GROUP BY
        1,
        2)
    SELECT
      a.date,
      COUNT(DISTINCT a.user_id) AS DAU,
      COUNT(DISTINCT (CASE WHEN b.ActiveDays >= 3 THEN a.user_id END)) AS DAU_Meet_Criteria
    FROM
      DATA a
    LEFT JOIN
      ACTIVE_DAYS b
    ON
      a.date = b.date
      AND a.user_id = b.user_id
    GROUP BY
      1
    ORDER BY
      1
    

    通过编辑date_sub 函数和第二个count(distinct... 语句中的case 语句,您可以实现一些替代逻辑。

    希望这会有所帮助。

    【讨论】:

    • 太好了,非常感谢。那我就不再追逐解析函数了,转而使用join方法。
    猜你喜欢
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2012-11-07
    • 2013-11-12
    • 2019-07-22
    • 2019-10-25
    相关资源
    最近更新 更多