こんにちは、 @kz_morita です。
Redshift に溜まったユーザーの行動ログを分析しようとして Window 関数について調べてました. Window関数をある程度理解するとかなり分析の幅が増えるので,今回はWindow関数について学んだことをまとめます.
PostgreSQL と Amazon Redshift について
Window関数の前に,Redshift と PostgreSQL の関係性について述べておきます.
Amazon Redshift の 公式サイト に書いてありますが,Redshift は PostgreSQL に基づいています.
基本的には共通しているところが多いですが,Amazon Redshift のほうがより分析ように特化しておりデータセットが巨大な場合や,SQLが複雑な場合に向いているようです.
ただし,頻繁に更新されたり,同時に複数SQLが実行されるような環境には向いていないようです.
Window 関数の書式
それでは早速 Window 関数の書き方について見ていきます.
Window 関数は主に SELECT 句 などで使用でき以下のような書式になります.
Window関数 OVER (
PARTITION BY パーティション
ORDER BY 並び順
ROWS Windowフレーム
)
具体的な例を上げます.
SELECT
user_id,
action,
datetime,
-- 各ユーザーごとに取った行動の新しい順で2番めの値を取得
NTH_VALUE(action, 2)
OVER (
PARTITION BY user_id
ORDER BY datetime DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)
-- ユーザーの行動ログ
FROM user_logs
上記の例を用いながら Window関数
, パーティション
,並び順
,Windowフレーム
の順に見ていきます.
Window 関数
Window 関数は,Windowという区切られた区間についての処理を行う関数になります.
NTH_VALUE(action, 2) -- <- ココ
OVER (
PARTITION BY user_id
ORDER BY datetime DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)
上記の例で言うところの,NTH_VALUE(action, 2)
という箇所が Window 関数になります.
Windowに対して使用する関数には大きく分けて2種類あり,Window関数としてしか使用できないものと,Group BY などでもしようできる集約関数があります.
Window 関数のみ
関数 | 説明 |
---|---|
CUME_DIST | パーティション 内の累積分布を計算.Windowフレームは指定できない |
FIRST_VALUE | Windowフレーム の最初の行の値を返します |
LAST_VALUE | Windowフレーム の最後の行の値を返します |
LAG | パーティション内の現在行より, 指定されたオフセットだけ前の行の値を返します. Windowフレームは指定できない |
LEAD | パーティション内の現在行より, 指定されたオフセットだけ後ろの行の値を返します. Windowフレームは指定できない |
NTH_VALUE | Windowの指定された行の値を返します |
ROW_NUMBER | パーティション内の行番号 |
RANK | 並び順に基づいて,ランク付けをします |
集約関数
関数 | 説明 |
---|---|
AVG | 平均 |
COUNT | 個数 |
MAX | 最大値 |
MIN | 最小値 |
SUM | 総和 |
すべての関数は 公式サイト を参照してください.
また,Window関数の種類によっては,パーティション,並び順,Windowフレームを省略できたり,はたまた必須であったりするので使用する際には上記の公式サイトをみて確認してみてください.
パーティション
パーティションは,どのような区間でデータを分けるかを指定します.概念としては GROUP BY と似ていますが,GROUP BY が区間を 1行に集約するのに対し,パーティションは集約されません.
NTH_VALUE(action, 2)
OVER (
PARTITION BY user_id -- <- ココ
ORDER BY datetime DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)
上記の例のように,PARTITION BY
に続いて区間をわけるキーとなるフィールドを指定します.ここでは,ユーザーごとの区間にログを分けている指定になります.
並び順
並び順は,パーティション内の区間のデータをどのように並び替えるかを指定します.
NTH_VALUE(action, 2)
OVER (
PARTITION BY user_id
ORDER BY datetime DESC -- <- ココ
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
)
通常の ORDER BY 句と同じような指定方法になります.この例では,ユーザーごとに行動ログを区間分けしその中で新しいモノ順に区間内をならべています.
Windowフレーム
Window フレームは順序付けされたパーティション内に対してさらに絞り込むことが出来ます.
書式としては,以下のようになります.
ROWS BETWEEN {開始行の指定} AND {終了行の指定}
開始行の指定は以下を指定できます.
指定 | 説明 |
---|---|
UNBOUNDED PRECEDING | パーティション内の先頭の行 |
CURRENT ROW | 現在の行 |
{N} PRECEDING | 現在行より,{N}行前 |
終了行は以下のように指定できます.
指定 | 説明 |
---|---|
UNBOUNDED FOLLOWING | パーティション内の最後の行 |
CURRENT ROW | 現在の行 |
{N} FOLLOWING | 現在行より,{N}行後 |
NTH_VALUE(action, 2)
OVER (
PARTITION BY user_id
ORDER BY datetime DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING -- <- ココ
)
上記の例だと,パーティション内のすべての行を指定しています.
まとめ
Redshift (PostgreSQL) の Window 関数について今回はまとめました. Window関数が使いこなせるようになると,一気に分析のしやすさがぐんと上がるのでユーザーの行動ログなどそういった分析をする際には,チェックしておくとよいかと思います.