3.3.3. ウィンドウ機能
Data Virtualization は ANSI SQL336 ウィンドウ機能を提供します。window 関数は、GROUP BY
句を使用せずに、集約関数を結果セットのサブセットに適用できます。window 関数は集約関数と似ていますが、OVER
句またはウィンドウ仕様を使用する必要があります。
使用方法
上記の構文では、集約
は任意の 集約関数 を参照できます。キーワードは、以下の分析関数 ROW_NUMBER、RANK、DENSE_RANK、PERCENT_RANK、CUME_DIST に存在します。FIRST_VALUE、LAST_VALUE、LEAD、LAG、NTH_VALUE、および NTILE analytical 関数もあります。詳細は、「collect al functions definitions」 を参照してください。
構文ルール
- ウィンドウ関数は、クエリー式の SELECT 句および ORDER BY 句でのみ表示されます。
- ウィンドウ関数は、互いにネストできません。
- 式によるパーティション設定や順序にサブクィーター参照を含めることはできません。
- ウィンドウ表示時に aggregate ORDER BY 句を使用できません。
- ウィンドウ仕様 ORDER BY 句はエイリアス名を参照したり、位置の順番を使用したりできません。
- ウィンドウ仕様が順序付けされている場合は、ウィンドウアグリゲートで DISTINCT を使用しない場合があります。
- Analytical value 関数は DISTINCT を使用せず、ウィンドウの仕様で順序付けを使用する必要があります。
- RANGE または ROWS では、ORDER BY 句を指定する必要があります。指定がない場合はデフォルトのフレームが RANGE UNBOUNDED PRECEDING です。指定しないと、デフォルトは CURRENT ROW になります。開始前と終了の組み合わせは許可されていません。たとえば、UNBOUNDED FOLLOWING は開始前も終了として許可される UNBOUNDED PRECEDING は許可されていません。
- RANGE は n PRECEDING または n FOLLOWING を使用することはできません。
分析関数定義
- ランク付け機能
- RANK(): 1 で始まる各パーティション内の一意の順序付け値ごとに数字を割り当てます。これにより、次のランクが前の行の数と同じになります。
- DENSE_RANK(): 次のランクが連続するように、各パーティション内の一意の順序付け値ごとに数字を割り当てます。
- PERCENT_RANK():(RANK - 1)/(RC - 1)でコンピュートされます。RC はパーティションの合計行数です。
CUME_DIST(): PR / RC として計算されます。PR はピアを含む行のランクであり、RC はパーティションの総行数です。
デフォルトでは、すべての値が整数になります。大きな値が必要な場合は例外が発生します。システムの org.teiid.longRanks を使用して、代わりに RANK、DENSE_RANK、および ROW_NUMBER は long 値を返します。
- 値関数
- FIRST_VALUE(val)- 指定の順序付けを持つウィンドウフレームの最初の値を返します。
- LAST_VALUE(val)- 指定の順序付けのあるウィンドウフレームで最後に確認された値を返します。
- LEAD(val [, offset [, default]]): 現在の行の前にあるオフセット行であるウインドウで順序付けされた値にアクセスします。このような行がない場合は、デフォルト値が返されます。指定されていない場合、オフセットは 1 で、デフォルトは null です。
- LAG(val [, offset [, offset [, default]]): 現在の行の背後にあるオフセット行であるウインドウで順序付けされた値にアクセスします。このような行がない場合は、デフォルト値が返されます。指定されていない場合、オフセットは 1 で、デフォルトは null です。
- NTH_VALUE(val, n)- ウィンドウフレームの nth val を返します。インデックスは 0 を超える必要があります。そのような値が存在しない場合は、null を返します。
- 行値関数
-
ROW_NUMBER()-
1
で始まるパーティションの各行に数字を割り当てます。 -
NTILE(n)- パーティションを、最大
1
でサイズ異なる n タイルに分割します。大きなタイルは、最初に順番に作成されます。N
は0
より大きい値である必要があります。
-
ROW_NUMBER()-
処理
ウィンドウ関数は、SELECT 句から出力を作成する直前に論理的に処理されます。GROUP BY 句が存在する場合、ウィンドウ関数はネストされた集約を使用できます。ウィンドウ関数の有無により、出力の順序には保証されません。SELECT ステートメントには、順序が予測できるように ORDER BY 句が必要です。
OVER 句の ORDER BY は、上レベルの ORDER BY と同じルールのプッシュダウンと処理ルールに従います。通常、null 処理はエンジンとプッシュダウン処理によって異なる可能性があるため、NULLS FIRST/LAST を指定する必要があります。また、異なるデフォルトの動作が異なる場合に、ソート動作を制御するシステムプロパティーも参照してください。
Data Virtualization は、同じウィンドウ仕様を持つすべてのウィンドウ関数を処理します。通常、一意のウィンドウ仕様ごとに SELECT 句に送信される行値を完全に渡す必要があります。ウィンドウの指定ごとに、この値は PARTITION BY 句に従ってグループ化されます。PARTITION BY 句が指定されていない場合、入力全体が単一のパーティションとして処理されます。
出力値のフレームは、analytical 関数または ROWS/RANGE
句の定義に基づいて決定されます。デフォルトのフレームは RANGE UNBOUNDED PRECEDING
です
。RANGE
は行とそのピアを一緒に計算します。ROWS
は、全行で計算します。ROW_NUMBER
などのほとんどの分析機能には暗黙の RANGE/ROWS
があります。そのため、異なる関数を指定できません。たとえば、ROW_NUMBER()OVER(order)
は代わりに count(*)OVER(order ROWS UNBOUNDED PRECEDING AND CURRENT ROW)とし
て表現できます。したがって、ピアの数に関係なく、すべての行に異なる値を割り当てます。
例: ウィンドウ結果
SELECT name, salary, max(salary) over (partition by name) as max_sal, rank() over (order by salary) as rank, dense_rank() over (order by salary) as dense_rank, row_number() over (order by salary) as row_num FROM employees
SELECT name, salary, max(salary) over (partition by name) as max_sal,
rank() over (order by salary) as rank, dense_rank() over (order by salary) as dense_rank,
row_number() over (order by salary) as row_num FROM employees
name | salary | max_sal | ランク | dense_rank | row_num |
---|---|---|---|---|---|
John | 100000 | 100000 | 2 | 2 | 2 |
Henry | 50000 | 50000 | 5 | 4 | 5 |
John | 60000 | 100000 | 3 | 3 | 3 |
Suzie | 60000 | 150000 | 3 | 3 | 4 |
Suzie | 150000 | 150000 | 1 | 1 | 1 |