WINDOW FUNCTION 演算子は、SQLにおける分析関数(ウィンドウ関数とも呼ばれる)を実装し、ウィンドウ内の関連行の結果を計算するために使用されます。
集約関数と異なり、集約関数は1つのグループから1行しか返せませんが、ウィンドウ関数は1つのグループから複数行を返すことができ、グループ内の各行はウィンドウに基づく論理計算の結果です。そのため、WINDOW FUNCTION を含むSQLを実行する際(一般的な形式は OVER(...))、実行計画を生成する際に WINDOW FUNCTION 演算子が割り当てられます。
例:WINDOW FUNCTION 演算子を含む実行計画
obclient> CREATE TABLE t1(c1 INT, c2 INT);
Query OK, 0 rows affected
obclient> INSERT INTO t1 VALUES(1, 1);
Query OK, 1 rows affected
obclient> INSERT INTO t1 VALUES(2, 2);
Query OK, 1 rows affected
obclient> INSERT INTO t1 VALUES(3, 3);
Query OK, 1 rows affected
Q1:
obclient> EXPLAIN SELECT MAX(c1) OVER(PARTITION BY c1 ORDER BY c2) FROM t1;
Query Plan:
| ========================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
----------------------------------------
|0 |WINDOW FUNCTION| |3 |45 |
|1 | SORT | |3 |44 |
|2 | TABLE SCAN |T1 |3 |37 |
========================================
Outputs & filters:
-------------------------------------
0 - output([T_FUN_MAX(T1.C1)]), filter(nil),
win_expr(T_FUN_MAX(T1.C1)), partition_by([T1.C1]), order_by([T1.C2, ASC]), window_type(RANGE), upper(UNBOUNDED PRECEDING), lower(CURRENT ROW)
1 - output([T1.C1], [T1.C2]), filter(nil), sort_keys([T1.C1, ASC], [T1.C2, ASC])
2 - output([T1.C1], [T1.C2]), filter(nil),
access([T1.C1], [T1.C2]), partitions(p0)
ウィンドウ関数で ORDER BY または PARTITION BY が指定されている場合、下層に SORT 演算子が割り当てられ、ソート結果がウィンドウ関数演算子に返されて使用されます。
上記の例では、Q1クエリの実行計画表示における outputs & filters の詳細列に、WINDOW FUNCTION 演算子の出力情報が以下のように詳細に示されています:
| 情報名 | 意味 |
|---|---|
| output | この演算子が出力する式。 |
| filter | この演算子のフィルタ条件。例では、WINDOW FUNCTION 演算子に filter が設定されていないため、nil となります。 |
| win_expr | ウィンドウ内で使用する集計関数。 例えば、Q1クエリは c1 列の最大値を求めるため、T_FUN_MAX(t1.c1) となります。 |
| partition_by | ウィンドウ内でどのようにグループ化するか。 例えば、Q1クエリは c1 列に基づいてグループ化するため、t1.c1 となります。 |
| order_by | ウィンドウ内でどのようにソートするか。 例えば、Q1クエリは c2 列に基づいてソートするため、t1.c2 となります。 |
| window_type | ウィンドウタイプ。RANGE と ROWS の2種類があります:
例えば、Q1クエリではウィンドウタイプが設定されていないため、デフォルトの RANGE 方式が選択されます。 |
| upper | ウィンドウの上境界を設定します:
例えば、Q1クエリではウィンドウの上境界を UNBOUNDED と PRECEDING の組み合わせ、つまり前方に無限として設定します。 |
| lower | ウィンドウの下境界を設定します。境界属性の設定は upper と同じです。例えば、Q1クエリではウィンドウの下境界を現在の行として設定します。 |