2017-06-13 2 views
0

Ich versuche, die durchschnittliche Zeit zwischen zwei Ereignissen in meiner Firebase-Analyse mithilfe von BigQuery zu ermitteln. Die Tabelle sieht etwa so aus:Big Query Compute Durchschnittliche Zeit zwischen zwei benutzerdefinierten Ereignissen

enter image description here

Ich mag würde die timstamp_micros für die LOGIN_CALL und LOGIN_CALL_OK Ereignisse zu sammeln, subtrahieren LOGIN_CALL von LOGIN_CALL_OK und berechnen den Durchschnitt für diese in allen Reihen.

#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` 

Ich habe es geschafft, entweder die niedrigen oder die hallo Zahlen aufzulisten, aber jedes Mal, wenn ich versuchen, jede Mathematik zu tun auf ihnen, dass ich in Fehler betreibe ich auseinander zu ziehen bin zu kämpfen. Dieser Ansatz scheint oben wie es funktionieren sollte, aber ich erhalte den folgenden Fehler:

Error: Scalar subquery produced more than one element

ich diesen Fehler zu lesen bedeutet, dass jeder der UNNEST() -Funktionen ein Array zurückgibt, und nicht einzelne Wert, der AVG verursacht zu Kotzen. Ich habe versucht, einmal zu ernest und einen "niedrigen" und "hallo" Namen auf die Werte anzuwenden, aber kann nicht herausfinden, wie man mit dem event_dim.name richtig filtert.

+0

Sie müssen eine Art ID haben, um LOGIN_CALL und LOGIN_CALL_OK zu verbinden, um einen sinnvollen Unterschied zwischen ihnen zu machen. –

+0

Nicht sicher, ob ich folge? Diese werden in der BigQuery DB in einzelne Zeilen gepackt ... die Namen der Ereignisse wären die ID, glaube ich? –

+0

Ah Entschuldigung Ich denke, ich folge jetzt ein bisschen weiter - es ist eine ID in der Tabelle, ich habe es oben nur nicht enthalten. –

Antwort

4

Ich teste diese eine nicht vollständig könnte aber vielleicht könnte für Sie arbeiten:

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') 
) 

I 3 Benutzer mit demselben Schema simuliert haben, die Sie in Firebase Schema haben.

Grundsätzlich habe ich zuerst die UNNEST Operation angewendet, um jeden Wert von event_dim.name zu haben. Dann angewendet Filter, um nur die Ereignisse zu erhalten, die Sie interessiert sind, das heißt "LOGIN_CALL" und "LOGIN_CALL_OK".

Wie oben erwähnt, müssen Sie eine Identifikation für diese Zeilen haben, da Sie ansonsten nicht wissen, welches Ereignis erfolgreich war. Deshalb nimmt die Partitionierung der analytischen Funktionen auch die user_dim.user_id als Eingabe.

Danach ist es nur TIMESTAMP Operationen, um die Unterschiede zu erhalten, wenn angemessen (wenn das führende Ereignis "LOGIN_CALL_OK" ist und die aktuelle "LOGIN_CALL" dann die Differenz nehmen. Dies wird in der CASE-Ausdruck ausgedrückt).

Sie können in der TIMESTAMP_DIFF Funktion wählen, welcher Teil des Datums Sie analysieren möchten, wie Sekunden, Minuten, Tage und so weiter.

+0

Danke, versuche es jetzt. –

+0

Abfrage läuft, aber ich bekomme nur "AVG dif 0.0" –

+0

Ja, wenn ich die AVG entfernen sieht es aus wie es entweder 0 oder Nullen für alle time_diffs bekommt. Es gibt keine Garantie, dass die Ereignisse direkt nebeneinander liegen, sie könnten durch andere Ereignisse getrennt sein (am häufigsten ist der Sitzungsbeginn). Dies scheint jedoch ein Schritt in die richtige Richtung zu sein, vielen Dank. –

Verwandte Themen