2014-12-19 8 views
5

Ich versuche, eine 28 Tage dauernde Summe in BigQuery mit der LAG-Funktion zu berechnen.BigQuery SQL für 28-Tage-Gleitfenster-Aggregat (ohne 28 Zeilen SQL schreiben)

Die Top-Antwort auf diese Frage

Bigquery SQL for sliding window aggregate

von Felipe Hoffa zeigt an, dass, dass Sie die LAG-Funktion nutzen können. Ein Beispiel dafür wäre:

SELECT 
    spend + spend_lagged_1day + spend_lagged_2day + spend_lagged_3day + ... + spend_lagged_27day as spend_28_day_sum, 
    user, 
    date 
FROM (
    SELECT spend, 
     LAG(spend, 1) OVER (PARTITION BY user ORDER BY date) spend_lagged_1day, 
     LAG(spend, 2) OVER (PARTITION BY user ORDER BY date) spend_lagged_2day, 
     LAG(spend, 3) OVER (PARTITION BY user ORDER BY date) spend_lagged_3day, 
     ... 
     LAG(spend, 28) OVER (PARTITION BY user ORDER BY date) spend_lagged_day, 
     user, 
     date 
    FROM user_spend 
) 

Gibt es eine Möglichkeit, dies zu tun, ohne 28 Zeilen SQL schreiben zu müssen!

Antwort

21

Die BigQuery-Dokumentation erklärt die Komplexität von Fensterfunktionen, die das Tool unterstützt, nicht gut, da nicht angegeben wird, welche Ausdrücke nach ROWS oder RANGE angezeigt werden können. Es unterstützt tatsächlich den SQL 2003-Standard für Fensterfunktionen, den Sie an anderen Stellen im Internet finden können, z. B. here.

Das bedeutet, Sie können den gewünschten Effekt mit einer einzigen Fensterfunktion erhalten. Der Bereich ist 27, weil es so viele Zeilen vor dem aktuellen in der Summe enthalten ist.

SELECT spend, 
     SUM(spend) OVER (PARTITION BY user ORDER BY date ROWS BETWEEN 27 PRECEDING AND CURRENT ROW), 
     user, 
     date 
FROM user_spend; 

Eine RANGE-Bindung kann auch sehr nützlich sein. Wenn in Ihrer Tabelle für einen Benutzer Daten fehlen, würden 27 PRECEDING-Zeilen mehr als 27 Tage zurückgehen, aber RANGE wird ein Fenster basierend auf den Datumswerten selbst erstellen. In der folgenden Abfrage ist das Datumsfeld ein BigQuery TIMESTAMP und der Bereich wird in Mikrosekunden angegeben. Ich rate Ihnen, wenn Sie Mathe wie diese in BigQuery abrechnen, testen Sie es gründlich, um sicherzustellen, dass es Ihnen die erwartete Antwort gibt.

SELECT spend, 
     SUM(spend) OVER (PARTITION BY user ORDER BY date RANGE BETWEEN 27 * 24 * 60 * 60 * 1000000 PRECEDING AND CURRENT ROW), 
     user, 
     date 
FROM user_spend;