查看过去30天的所有使用情况(按用户和滚动分组)

时间:2018-07-18 21:39:24

标签: sql google-bigquery

我有一个文件,其中记录了我们产品的所有使用情况,包括用户ID,拨打电话的次数和拨打电话的日期(按用户ID汇总到该日期)。

user_id | num_calls |日期

123 | 32 | 2018-04-17

435 | 21 | 2018-04-17

123 | 35 | 2018-04-18

435 | 10 | 2018-04-18

123 | 20 | 2018-04-19

435 | 90 | 2018-04-20

我想生成一个图表,以显示过去和以后每一天的用户,在该日期之前(包括该天)的30天内处于活动状态的用户,以及他们在该30天内的通话次数。最终,我将使用它来设置给定30天内“高使用率”的各种阈值。看起来像这样:

user_id | num_calls_in_previous_30_days |日期

123 | 32 | 2018-04-17

435 | 21 | 2018-04-17

123 | 67 | 2018-04-18

435 | 31 | 2018-04-18

123 | 87 | 2018-04-19

435 | 31 | 2018-04-19

123 | 87 | 2018-04-20

435 | 121 | 2018-04-20

我遇到的问题是,当我尝试使用窗口功能

总和(num_calls)超过(按ID划分ORDER BY UNIX_SECONDS(时间戳(日期))范围在2505600开头和当前行之间)

我只获得在每个特定日期处于活动状态的用户在最近30天内的呼叫总数,而不是包括在该日期之前30天内处于活动状态的所有用户及其在该时间段内的使用情况。使用上面的相同数据,看起来像这样:

user_id | num_calls_in_previous_30_days |日期

123 | 32 | 2018-04-17

435 | 21 | 2018-04-17

123 | 67 | 2018-04-18

435 | 31 | 2018-04-18

123 | 87 | 2018-04-19

435 | 121 | 2018-04-20

我尝试了另一种方法,即从每个日期获取前30天的所有唯一的user_id,但是我不确定如何将其与现有的使用情况数据结合起来以获得期望的结果。

我确定这里有一个简单的解决方案,但是我花了几个小时,似乎无法解决这个问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

以下示例适用于BigQuery标准SQL

#standardSQL
WITH dates AS (
  SELECT DATE
  FROM (
    SELECT MIN(DATE) start, MAX(DATE) finish
    FROM `project.dataset.table`
  ), UNNEST(GENERATE_DATE_ARRAY(start, finish)) DATE
), users AS (
  SELECT DISTINCT user_id 
  FROM `project.dataset.table`
)
SELECT user_id, num_calls, DATE,
  SUM(num_calls) OVER (win30days) num_calls_in_previous_30_days
FROM users
CROSS JOIN dates
LEFT JOIN `project.dataset.table` USING(DATE, user_id)
WINDOW win30days AS (
  PARTITION BY user_id 
  ORDER BY UNIX_SECONDS(TIMESTAMP(DATE)) 
  RANGE BETWEEN 2505600 PRECEDING AND CURRENT ROW
)

您可以使用下面的问题中的虚拟数据进行测试,操作

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 123 user_id, 32 num_calls, DATE '2018-04-17' DATE UNION ALL
  SELECT 435, 21, '2018-04-17' UNION ALL
  SELECT 123, 35, '2018-04-18' UNION ALL
  SELECT 435, 10, '2018-04-18' UNION ALL
  SELECT 123, 20, '2018-04-19' UNION ALL
  SELECT 435, 90, '2018-04-20' 
), dates AS (
  SELECT DATE
  FROM (
    SELECT MIN(DATE) start, MAX(DATE) finish
    FROM `project.dataset.table`
  ), UNNEST(GENERATE_DATE_ARRAY(start, finish)) DATE
), users AS (
  SELECT DISTINCT user_id 
  FROM `project.dataset.table`
)
SELECT user_id, num_calls, DATE,
  SUM(num_calls) OVER (win30days) num_calls_in_previous_30_days
FROM users
CROSS JOIN dates
LEFT JOIN `project.dataset.table` USING(DATE, user_id)
WINDOW win30days AS (
  PARTITION BY user_id 
  ORDER BY UNIX_SECONDS(TIMESTAMP(DATE)) 
  RANGE BETWEEN 2505600 PRECEDING AND CURRENT ROW
)
-- ORDER BY DATE, user_id

结果为

Row user_id num_calls   DATE            num_calls_in_previous_30_days    
1   123     32          2018-04-17      32   
2   435     21          2018-04-17      21   
3   123     35          2018-04-18      67   
4   435     10          2018-04-18      31   
5   123     20          2018-04-19      87   
6   435     null        2018-04-19      31   
7   123     null        2018-04-20      87   
8   435     90          2018-04-20      121