メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
ウィンドウ関数は、現在の行に関連する行の集合にわたって値を計算します。GROUP BY のようにそれらの行を 1 つの出力行にまとめることはありません。以前はサブクエリやアプリケーション層での処理を必要とした分析クエリを可能にします。

ウィンドウ関数と GROUP BY の違い

2 つ目のクエリは注文ごとに 1 行を返し、各行にはその顧客の合計も表示されます。GROUP BY にはこれができません。個々の行を取り除いてしまうからです。

OVER 句

すべてのウィンドウ関数は、ウィンドウ — 計算の対象となる行の集合 — を定義する OVER 句を使います。
空の OVER() は、ウィンドウが結果セット全体であることを意味します。

ランキング関数

出力の例を示します。

PARTITION BY: グループごとのランキング

結果セット全体ではなくグループ内で順位を付けるには、PARTITION BY を追加します。
各顧客の最新の注文を取得するには次のようにします。

LAG と LEAD: 隣接する行へのアクセス

LAG は前の行に、LEAD は後の行にアクセスします。自己結合は不要です。
どちらの関数も、省略可能なオフセット(デフォルトは 1)と、隣接する行が存在しないときのデフォルト値を受け取ります。

累計と移動平均

ROWS BETWEEN を使ってフレーム — 計算に含める行の部分集合 — を定義します。
よく使うフレームの指定は次のとおりです。

よくある質問

WHERE 句でウィンドウ関数の結果を使って絞り込めますか?

いいえ。ウィンドウ関数は WHERE の後に評価されます。ウィンドウ関数の結果で絞り込むには、クエリをサブクエリまたは CTE で包みます。

フレーム句の ROWS と RANGE の違いは何ですか?

ROWS は物理的な行を数えます。RANGE は同じ ORDER BY の値を持つ行をまとめます。ほとんどの用途(累計、移動平均)では、ROWS が期待どおりの振る舞いをします。RANGE は、順序付けの列に同じ値があるときに意外な結果を生むことがあります。

ウィンドウ関数はインデックスを使いますか?

ウィンドウ関数はウィンドウの計算自体にはインデックスを使いませんが、クエリは WHERE 句にインデックスを使って処理対象の行を減らせます。複雑なウィンドウクエリでは、実行計画を理解するために MySQL の EXPLAIN の読み方が役立ちます。

トラブルシューティング

関連項目