Выберите отдельную группу пользователей по временному диапазону Google - BigQuery SQL - PullRequest
0 голосов
/ 20 сентября 2019

Выбор отдельной группы пользователей по временному диапазону

Как мне сделать ссылку выше в версии SQL для больших запросов Google?

Обновление с подробностями:

У меня есть таблица со следующей информацией

 |day| user_id  

Я хочу рассчитать количество различных идентификаторов user_id длядата:

  1. на эту дату
  2. на эту неделю до этой даты (неделя до даты)
  3. за месяц до этой даты (месяц до даты)

Пример таблицы ввода:

 | day        | user_id    
 | 2013-01-01 | 1          
 | 2013-01-03 | 3          
 | 2013-01-06 | 4          
 | 2013-01-07 | 4          

Ожидаемый вывод:

 | day        | time_series | cnt        |                 
 | 2013-01-01 | D           | 1          |                 
 | 2013-01-01 | W           | 1          |                 
 | 2013-01-01 | M           | 1          |                 
 | 2013-01-03 | D           | 1          |                 
 | 2013-01-03 | W           | 2          |                 
 | 2013-01-03 | M           | 2          |                 
 | 2013-01-06 | D           | 1          |                 
 | 2013-01-06 | W           | 1          |                 
 | 2013-01-06 | M           | 3          |                 
 | 2013-01-07 | D           | 1          |                 
 | 2013-01-07 | W           | 1          |                 
 | 2013-01-07 | M           | 3          |

PS Аналогичный вопрос был задан для postgresql - но мне нужна версия для BigQuery

1 Ответ

0 голосов
/ 21 сентября 2019

Ниже для BigQuery Standard SQL

Опция # 1

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2013-01-01' day, 1 user_id UNION ALL
  SELECT '2013-01-03', 3 UNION ALL
  SELECT '2013-01-06', 4 UNION ALL
  SELECT '2013-01-07', 4 
)
SELECT day, 'D' series, COUNT(DISTINCT user_id) users 
FROM `project.dataset.table` GROUP BY day 
UNION ALL
SELECT DISTINCT day, 'W', (SELECT COUNT(DISTINCT id) FROM UNNEST(users) id) 
FROM (
  SELECT day,  ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, WEEK) ORDER BY day) users
  FROM `project.dataset.table`
)
UNION ALL
SELECT DISTINCT day, 'M', (SELECT COUNT(DISTINCT id) FROM UNNEST(users) id)
FROM (
  SELECT day,  ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, MONTH) ORDER BY day) users
  FROM `project.dataset.table`
)
ORDER BY day, CASE series WHEN 'D' THEN 1 WHEN 'W' THEN 2 ELSE 3 END

с результатом

Row day         series  users    
1   2013-01-01  D       1    
2   2013-01-01  W       1    
3   2013-01-01  M       1    
4   2013-01-03  D       1    
5   2013-01-03  W       2    
6   2013-01-03  M       2    
7   2013-01-06  D       1    
8   2013-01-06  W       1    
9   2013-01-06  M       3    
10  2013-01-07  D       1    
11  2013-01-07  W       1    
12  2013-01-07  M       3    

Опция # 2 - основано на вышеуказанной версии, но объединяет три запроса в один

#standardSQL
SELECT DISTINCT day, d_users,
  (SELECT COUNT(DISTINCT id) FROM UNNEST(w_users) id) w_users,
  (SELECT COUNT(DISTINCT id) FROM UNNEST(m_users) id) m_users
FROM (
  SELECT day,  
    COUNT(DISTINCT user_id) OVER(PARTITION BY day) d_users,
    ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, WEEK) ORDER BY day) w_users,
    ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, MONTH) ORDER BY day) m_users
  FROM `project.dataset.table`
)
ORDER BY day  

Если применить к одним и тем же данным - результат

Row day         d_users w_users m_users  
1   2013-01-01  1       1       1    
2   2013-01-03  1       2       2    
3   2013-01-06  1       1       3    
4   2013-01-07  1       1       3      

Опция # 3 - если по какой-то причине вам нужен результат разворота / выравнивания опции # 2

#standardSQL
SELECT day, series, users
FROM (
  SELECT DISTINCT day, d_users,
    (SELECT COUNT(DISTINCT id) FROM UNNEST(w_users) id) w_users,
    (SELECT COUNT(DISTINCT id) FROM UNNEST(m_users) id) m_users
  FROM (
    SELECT day,  
      COUNT(DISTINCT user_id) OVER(PARTITION BY day) d_users,
      ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, WEEK) ORDER BY day) w_users,
      ARRAY_AGG(user_id) OVER(PARTITION BY DATE_TRUNC(day, MONTH) ORDER BY day) m_users
    FROM `project.dataset.table`
  )
), UNNEST([STRUCT('D' AS series, d_users AS users), ('W', w_users), ('M', m_users)]) 
ORDER BY day   

, который дает тот же результат, что и в опции # 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...