2017-11-27 6 views
1

標準のSQL BigQueryでFILTER(http://modern-sql.com/feature/filter)の動作をエミュレートする方法はありますか?私がする必要があるだろうかBigQueryでのイベントの最新性を計算するウィンドウのフィルタパーティション

は次のとおりです。本質的には

SELECT MAX(date) FILTER (WHERE event_happend = 1) OVER ( PARTITION BY user_id ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM ...

は、私は特定のイベントが現在の行の日より前に発生した最新の日付をうまくする必要があります。 列event_happenedは値0とを持ちますが、現在の行の日付より前にイベントが発生した最新の日付(event_happened = 1)が必要です。

+0

なぜROWSではなくRANGEを使用するのはなぜですか?次に、現在の行の値を除外できます。 –

+0

@ElliottBrossardあなたの提案をお寄せいただきありがとうございます。しかし、私はRANGEを使用してどのように私を助けてくれるのかよく分かりません。どうぞあなたは詳しく教えていただけますか?私はまた、私の質問に明確にするために、次のように追加しました: "列event_happenedは0と1の値を取る、私は現在の行の日付の前にevent_happened = 1イベントが発生した最新の日付が必要です。 – user3531907

+0

@ElliottBrossard私も質問の日付列の名前を更新しました - 混乱していた当初の選択 – user3531907

答えて

1

FILTERの動作をエミュレートする方法はありますか?

#standardSQL 
SELECT 
    MAX(IF(event_happend = 1, date, null)) 
    OVER (
    PARTITION BY user_id 
    ORDER BY date ASC 
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
) 
    FROM 
    ... 
+0

これは、ウィンドウ内に同じ 'date'値が複数存在すると、間違った答えを与える可能性があります。 'RANGE'。 –

+0

:o) 'MAX(IF(event_happend = 1、date、null))'は 'FILTER'に関する答えの中核です - 私はOPによって期待される正確なロジックが本当に明確でないので、元の質問から何も変更していません –

+0

私は同意しますが、OPは「現在の行の日付より前に」と述べていたので、それを考慮に入れることが重要と思われました。 –

2

これを試してみてください:

#standardSQL 
WITH SampleData AS (
    SELECT 1 AS user_id, DATE '2017-11-02' AS date, 1 AS event_happend UNION ALL 
    SELECT 1, DATE '2017-11-03', 0 UNION ALL 
    SELECT 1, DATE '2017-11-04', 1 UNION ALL 
    SELECT 1, DATE '2017-11-04', 1 UNION ALL 
    SELECT 1, DATE '2017-11-05', 0 UNION ALL 
    SELECT 2, DATE '2017-11-10', 1 UNION ALL 
    SELECT 2, DATE '2017-11-11', 0 UNION ALL 
    SELECT 2, DATE '2017-11-20', 0 UNION ALL 
    SELECT 2, DATE '2017-11-21', 1 
) 
SELECT 
    user_id, 
    date, 
    MAX(IF(event_happend = 1, date, NULL)) OVER (
    PARTITION BY user_id ORDER BY UNIX_DATE(date) 
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
) AS max_date 
FROM SampleData; 

私は何が起こっているかを確認するためにuser_iddateが含まれています。ここではRANGEを使用することが重要です。ROWSを使用すると、ウィンドウの前の行に同じdateの値がある場合があります。 RANGE1 PRECEDINGを使用すると、ウィンドウ内のすべての行が現在の値よりも小さいdate値を持つように強制できます。

関連する問題