2017-06-13 89 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的空值。不能保證事件彼此相鄰,它們可以被其他事件分開(會話開始是最常見的)。這看起來像是朝着正確方向邁出的一步,非常感謝。 –

相關問題