Таблица распределения продолжительности сеанса в Firebase
Я хочу создать таблицу распределения сеанса в BigQuery на основе данных сеанса Firebase. Я хочу создать наиболее эффективный запрос, который я хочу запускать ежемесячно. Вывод должен выглядеть так:
Я повторно использовал код из этого примера, и моя первая попытка приведена ниже, но нельзя агрегировать агрегации. Итак, мне пришлось подумать о другом пути...
SELECT
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) = 0 THEN app_instance_id END) AS sess_length_seconds_0,
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) BETWEEN 0 AND 10 THEN sess_id END) AS sess_length_seconds_10_30
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 30 AND (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) <= 60 THEN app_instance_id END) AS sess_length_seconds_30-60,
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 60 AND (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) <= 180 THEN app_instance_id END) AS sess_length_seconds_60-180,
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 180 AND (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) <= 600 THEN app_instance_id END) AS sess_length_seconds_180-600,
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 600 AND (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) <= 1800 THEN app_instance_id END) AS sess_length_seconds_600-1800,
COUNT(CASE WHEN (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 1800 THEN app_instance_id END) AS 1800_plus_sess_length_seconds
FROM (SELECT *, SUM(session_start) OVER(PARTITION BY app_instance_id ORDER BY min_time) sess_id
FROM (SELECT *, IF(previous IS null OR (min_time-previous)>(30*60*1000*1000), # sessions broken by this inactivity
1, 0) session_start FROM (SELECT *, LAG(max_time, 1) OVER(PARTITION BY app_instance_id ORDER BY max_time) previous
FROM (SELECT
user_dim.app_info.app_instance_id,
user_dim.device_info.mobile_model_name,
user_dim.device_info.platform_version,
(SELECT MIN(timestamp_micros) FROM UNNEST(event_dim)) min_time,
(SELECT MAX(timestamp_micros) FROM UNNEST(event_dim)) max_time
FROM `firebase-public-project.com_firebase_demo_IOS.app_events_*`
WHERE (_TABLE_SUFFIX BETWEEN '20170701' AND '20170731')
)
)
)
)
GROUP BY 1, 2, 3, 4
ORDER BY 1, 2, 3, 4
Во втором запросе я собрал предложение "Имея", которое, кажется, работает, но это занимает довольно много времени!
#standardSQL
SELECT COUNT(app_instance_id)
FROM (SELECT *, SUM(session_start) OVER(PARTITION BY app_instance_id ORDER BY min_time) sess_id
FROM (SELECT *, IF(previous IS null OR (min_time-previous)>(30*60*1000*1000),1, 0) session_start
FROM (SELECT *, LAG(max_time, 1) OVER(PARTITION BY app_instance_id ORDER BY max_time) previous
FROM (SELECT user_dim.app_info.app_instance_id,
user_dim.device_info.mobile_model_name,
user_dim.device_info.platform_version,
(SELECT MIN(timestamp_micros) FROM UNNEST(event_dim)) min_time,
(SELECT MAX(timestamp_micros) FROM UNNEST(event_dim)) max_time
FROM `firebase-public-project.com_firebase_demo_IOS.app_events_*`
WHERE (_TABLE_SUFFIX BETWEEN '20170701' AND '20170731')
)
)
)
)
HAVING (ROUND((MAX(max_time)-MIN(min_time))/(1000*1000),1)) > 1800
Вопросы:
- Я хочу убедиться на 100 %, должен ли я считать экземпляры приложений (а не идентификаторы сеансов)?
- Есть ли более эффективный способ объединить все диапазоны распределения одним запросом (а не индивидуально, как в моем втором примере)? Я был бы признателен, если бы вы поделились примером кода, как добавить дистрибутивы вместе, сохраняя при этом максимально эффективный запрос.
- Я также создал поток для пользовательской (не Session) таблицы рассылки здесь.