滚动前几天在 bigquery 中也活跃的活跃用户
Rolling active users that were also active in previous days in bigquery
我想计算在过去 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 进行分组,并且使用 window 函数对前 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 |
你可能是对的,有一些合适的 window 函数可以实现这一点,但如果有的话我不熟悉它们。
然而,由于没有现成的解决方案,这里有一个仅使用连接的工作方法:
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 语句,您可以实现一些替代逻辑。
希望对您有所帮助。
我想计算在过去 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 进行分组,并且使用 window 函数对前 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 |
你可能是对的,有一些合适的 window 函数可以实现这一点,但如果有的话我不熟悉它们。
然而,由于没有现成的解决方案,这里有一个仅使用连接的工作方法:
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 语句,您可以实现一些替代逻辑。
希望对您有所帮助。