2017-06-13 93 views
0

我试图确定使用BigQuery的Firebase分析中两个事件之间的平均时间。该表看起来是这样的:大查询计算两个自定义事件之间的平均时间

enter image description here

我想收集的LOGIN_CALL和LOGIN_CALL_OK事件timstamp_micros,从LOGIN_CALL_OK减去LOGIN_CALL并在所有行计算平均此。

#standardSQL 
SELECT AVG(
(SELECT 
    event.timestamp_micros 
FROM 
    `table`, 
    UNNEST(event_dim) AS event 
where event.name = "LOGIN_CALL_OK") - 
(SELECT 
    event.timestamp_micros 
FROM 
    `table`, 
    UNNEST(event_dim) AS event 
where event.name = "LOGIN_CALL")) 
from `table` 

我已经成功地列出无论是低或喜的数字,但任何时候,我尝试做对他们的任何数学我碰上,我奋力拉开错误。上面的这种做法似乎像它应该工作,但我得到以下错误:

Error: Scalar subquery produced more than one element

我看了这个错误意味着每个UNNEST的()函数将返回一个数组,而不是这是造成AVG单值BARF。我尝试过一次,并对这些值应用“低”和“高”名称,但无法弄清楚如何正确使用event_dim.name进行过滤。

+0

您需要有某种ID才能连接LOGIN_CALL和LOGIN_CALL_OK以在它们之间做有意义的区别。 –

+0

不确定关注?在BigQuery DB中,这些都被打包成单行......事件的名称将会是我相信的ID? –

+0

对不起,我想我现在有点进一步了 - 表中有一个ID,我只是没有包括在上面。 –

回答

4

我不能完全测试此人,但也许这会为你工作:

WITH data AS(
    SELECT STRUCT('1' as user_id) user_dim, ARRAY< STRUCT<date string, name string, timestamp_micros INT64> > [('20170610', 'EVENT1', 1497088800000000), ('20170610', 'LOGIN_CALL', 1498088800000000), ('20170610', 'LOGIN_CALL_OK', 1498888800000000), ('20170610', 'EVENT2', 159788800000000), ('20170610', 'LOGIN_CALL', 1599088800000000), ('20170610', 'LOGIN_CALL_OK', 1608888800000000)] event_dim union all 
    SELECT STRUCT('2' as user_id) user_dim, ARRAY< STRUCT<date string, name string, timestamp_micros INT64> > [('20170610', 'EVENT1', 1497688500400000), ('20170610', 'LOGIN_CALL', 1497788800000000)] event_dim UNION ALL 
    SELECT STRUCT('3' as user_id) user_dim, ARRAY< STRUCT<date string, name string, timestamp_micros INT64> > [('20170610', 'EVENT1', 1487688500400000), ('20170610', 'LOGIN_CALL', 1487788845000000), ('20170610', 'LOGIN_CALL_OK', 1498888807700000)] event_dim 
) 

SELECT 
    AVG(time_diff) avg_time_diff 
FROM(
SELECT 
    CASE WHEN e.name = 'LOGIN_CALL' AND LEAD(NAME,1) OVER(PARTITION BY user_dim.user_id ORDER BY timestamp_micros ASC) = 'LOGIN_CALL_OK' THEN TIMESTAMP_DIFF(TIMESTAMP_MICROS(LEAD(TIMESTAMP_MICROS, 1) OVER(PARTITION BY user_dim.user_id ORDER BY timestamp_micros ASC)), TIMESTAMP_MICROS(TIMESTAMP_MICROS), day) END time_diff 
FROM data, 
UNNEST(event_dim) e 
WHERE e.name in ('LOGIN_CALL', 'LOGIN_CALL_OK') 
) 

我模拟3个用户与您在Firebase Schema具有相同的架构。

基本上,我首先应用了UNNEST操作,以使每个值为event_dim.name。然后应用筛选器以仅获取您感兴趣的事件,即“LOGIN_CALL”和“LOGIN_CALL_OK”。

正如上面没啥评论,你需要有一定的识别这些行作为否则你不会知道哪个事件成功这所以这就是为什么的分析功能分区取user_dim.user_id作为输入,以及。

在此之后,它只是TIMESTAMP操作,以获得差异在适当的时候(当领先的事件是“LOGIN_CALL_OK”和当前一个是“LOGIN_CALL”然后走差异化,这是在CASE表达式来表示)。

您可以在TIMESTAMP_DIFF函数中选择要分析日期的哪一部分,如秒,分钟,日等。

+0

谢谢,现在试用它。 –

+0

查询运行,但我只是得到“平均差0.0” –

+0

是的,如果我删除AVG它看起来像是得到0或所有time_diffs的空值。不能保证事件彼此相邻,它们可以被其他事件分开(会话开始是最常见的)。这看起来像是朝着正确方向迈出的一步,非常感谢。 –

相关问题