2016-09-30 3 views
1

Betrachten Sie dieses Schema einer BigQuery Tabelle:Konzernwerte durch kontinuierliche Perioden in BigQuery

+---------------------------------------+ 
|ServiceId |UserId |Date    | 
+---------------------------------------+ 
|s1  |u1  |2016|09|01 00:00:00 | 
|s1  |u1  |2016|09|02 00:00:00 | 
|s1  |u2  |2016|09|02 12:00:00 | 
|s1  |u2  |2016|09|05 00:00:00 | 
|s1  |u1  |2016|09|10 12:00:00 | 
|s2  |u1  |2016|09|06 00:00:00 | 
|s2  |u2  |2016|09|10 00:00:00 | 
|s2  |u2  |2016|09|10 12:00:00 | 
|s2  |u2  |2016|09|11 12:00:00 | 
+---------------------------------------+ 

Es die Verwendung bestimmter Ressourcen des Systems durch einen identifizierten Benutzer darstellt. Es funktioniert wie ein Protokoll von Aktivitäten.

Ich brauche eine Abfrage, mit der ich die kontinuierliche Nutzung einer Ressource im Laufe der Zeit abrufen kann. Da die Tabelle keine "Start" - und "End" -Daten enthält, wird das Ende als der letzte protokollierte Tag in der Periode betrachtet.

Zwei Daten werden als aufeinanderfolgend betrachtet, wenn sie höchstens 24 Stunden voneinander entfernt sind.

Dies ist die erwartete Ausgabe dieser Abfrage mit der angegebenen Tabelle:

+-------------------------------------------------------------+ 
|ServiceId |UserId |StartDate   |EndDate    | 
+-------------------------------------------------------------+ 
|s1   |u1  |2016|09|01 00:00:00 |2016|09|02 00:00:00 | 
|s1   |u2  |2016|09|02 12:00:00 |2016|09|02 12:00:00 | 
|s1   |u2  |2016|09|05 00:00:00 |2016|09|05 00:00:00 | 
|s1   |u1  |2016|09|10 12:00:00 |2016|09|10 12:00:00 | 
|s2   |u1  |2016|09|06 00:00:00 |2016|09|06 00:00:00 | 
|s2   |u2  |2016|09|10 00:00:00 |2016|09|11 12:00:00 | 
+-------------------------------------------------------------+ 

Mit anderen Worten: Ich muß durch einen Benutzer Zeiten kontinuierlicher Nutzung eines Dienstes identifizieren.

Die Dokumentation der Fensterfunktionen auf BigQuery (here und here) hat keine klaren Beispiele für diese Art von Anwendungsfall (in der Tat haben sie keine Beispiele mit Datumsangaben überhaupt).

Wie kann das mit BigQuery gemacht werden?

Danke.

Antwort

2

Hmmm. . . Ich denke, dass es so etwas wie folgt aussehen würde:

select serviceid, userid, min(date), max(date) 
from (select t.*, 
      sum(case when dateadd(prev_date, 1, "hour") < date then 1 else 0 end) over (partition by serviceid, userid order by date) as grp 
     from (select t.*, 
        lag(date) over (partition by serviceid, userid order by date) as prev_date 
      from t 
      ) t 
    ) t 
group by serviceid, userid, grp; 

Was dies bedeutet ist zu identifizieren, wenn es größer als eine 1-stündige Pause ist, eine Flagge von 1 zugeordnet werden, wenn dies der Fall ist. Dann führt es eine kumulative Summe des Flags aus und verwendet es zur Aggregation.

+0

Ich habe es versucht, und es funktionierte mit einigen Verbesserungen: 'prev_date' sollte mit einer' USEC_TO_TIMESTAMP' Funktion (wegen eines Fehlers mit der 'lag'-Funktion und Zeitstempeln, mehr Infos [hier] (https: //) code.google.com/p/google-bigquery/issues/detail?id=204)) und die Zahlen innerhalb des Vergleichs sollten umgeschaltet werden ('then 1 else 0'). –

+0

Standard-SQL hat dieses Problem nicht, wenn es hilft. https://cloud.google.com/bigquery/sql-reference/ –