ウィンドウ関数の構文と使用法¶
Snowflakeは、 ウィンドウ関数 として知られる分析的な SQL 関数を多数サポートしています。各機能の詳細については、個々のリファレンスページに記載されています。このセクションの目的は、 OVER 句の主なコンポーネントの詳細な構文を含め、ウィンドウ関数の一部またはすべてに適用される一般的な参照情報を提供することです:
PARTITION BY 句
ORDER BY 句
ウィンドウフレーム構文
ウィンドウ関数、ランク関連関数、またはウィンドウフレーム関数の知識が少ないユーザーは、 ウィンドウ関数を使ったデータ分析 にある概念についての資料に目を通すことをお勧めします。
構文¶
条件:
条件:
パラメーター¶
OVER( [ windowDefinition ] )この関数がウィンドウ関数として使用されることを指定し、関数が動作するウィンドウを指定します。OVER 句には括弧を入れなければなりませんが、当該関数の要件によっては空でもよいです。空の OVER 句はパーティションを持たず、デフォルトのウィンドウ・フレームを意味します。
PARTITION BY expr1製品、都市、年などのパーティションに行をグループ化します。入力行はパーティションごとにグループ化され、各パーティションに対して関数が計算されます。PARTITION BY 句は任意です。行の集合を1つのパーティションとして分析することができます。
ORDER BY expr2各パーティション内の行、またはパーティションが指定されていない場合は行全体の順序を指定します。この ORDER BY 句は、クエリの最終結果で返されるすべての行の順序を制御する ORDER BY 句とは異なります。ORDER BY 句は一部のウィンドウ関数では任意ですが、他の関数では必須です。例えば、 RANK や NTILE のようなランキング・ウィンドウ関数は、入力データが意味のある順番に並んでいる必要があります。
ウィンドウ関数の ORDER BY 句は、 ASC/DESC (昇順/降順)の順序と NULL の処理に関して、クエリのメイン ORDER BY 句と同様の規則に従います。詳細については、 ORDER BY をご参照ください。
注釈
ウィンドウ関数のORDER BY句は、
OVER (PARTITION BY 1 ORDER BY 2)のような順序位置の使用をサポートしていません。このコンテキストでは、2は定数2として解釈されます。クエリの2番目の列は参照しません。さまざまな関数が ORDER BY 句をさまざまな方法で処理します。
一部のウィンドウ関数には ORDER BY 句が必要です。
一部のウィンドウ関数では、 ORDER BY 句が禁止されています。
一部のウィンドウ関数は、存在する場合は ORDER BY 句を使用しますが、必須ではありません。
ウィンドウ関数の中には、 ORDER BY 句に暗黙のウィンドウフレームを適用するものがあります。詳細については、 ウィンドウフレームの使用上の注意 をご参照ください。
{ ROWS | RANGE }物理的な行数 (ROWS) または論理的に計算された行数 (RANGE) を定義します。範囲ベースと行ベースのウィンドウフレーム をご参照ください。
どちらのタイプのフレームも、暗黙的な名前付き境界または明示的なオフセット値を使用して、始点と終点を指定します。名前付きバウンダリーは、キーワード CURRENT ROW 、 UNBOUNDED PRECEDING 、 UNBOUNDED FOLLOWING で定義されます。明示的なオフセットは、数値または間隔(
n PRECEDINGまたはn FOLLOWING)で定義されます。
{ RANGE BETWEEN n PRECEDING | n FOLLOWING }明示的なオフセットを持つ範囲ベースのウィンドウフレームを指定します。
明示的なオフセットを持つ RANGE BETWEEN ウィンドウ・フレームは、 ORDER BY 式を1つだけ持つ必要があります。その式には次のデータ型がサポートされています。:
DATE, TIMESTAMP, TIMESTAMP_LTZ , TIMESTAMP_NTZ (DATETIME) , TIMESTAMP_TZ
INT 、 FLOAT などを含む NUMBER
TIME および他のSnowflakeデータ型は、このタイプのウィンドウフレームが使用されている場合はサポートされません。その他のウィンドウ・フレームについては、 ORDER BY 式で、 VARCHAR のような他のデータ型を使うことができます。
RANGE BETWEEN ウィンドウフレームの場合、 n は符号なし定数(0を含む正の数値)または正の INTERVAL 定数である必要があります:
expr2が数値データ型の場合、nは符号なし定数である必要があります。expr2が TIMESTAMP データ型の場合、nは INTERVAL 定数 である必要があります。例:INTERVAL '12 hours'またはINTERVAL '3 days'。expr2が DATE データ型である場合、nは符号なし定数でも INTERVAL 定数でもよいですが、フレームの開始と終了では、nの値に同じデータ型を使用する必要があります。
ORDER BY 式が昇順の場合(ASC)、構文
n FOLLOWINGは「x より大きい(または遅い)値を持つ行」を意味し、n PRECEDINGは「x より小さい(または早い)値を持つ行」を意味し、 x は現在の行の ORDER BY 値です。ORDER BY 式が降順(DESC)の場合は、その逆になります。(オフセット0 PRECEDINGと0 FOLLOWINGは CURRENT ROW と等価です)。
RANGE BETWEEN の制限事項¶
以下のウィンドウ関数のサブセットは、明示的なオフセットを持つ RANGE BETWEEN 構文をサポートしています:
STDDEV, STDDEV_SAMP、 STDDEV_POP (およびエイリアス)
VARIANCE , VARIANCE_SAMP、 VARIANCE_POP (およびエイリアス)
加えて、次のことにも注意してください。
これらの関数の DISTINCT バージョンはこの構文をサポートしていません。
この構文で COUNT window 関数を使用する場合、以下の制限が適用されます。
入力引数は1つのみ。
COUNT(table.*)ワイルドカード・クエリはサポートされていません。たとえば、次は実行できません。
フレームの開始位置と終了位置が論理的に逆転するようなフレームを指定することはできません。例えば、以下のフレームは、フレームの終了行が開始行より前にあるため、エラーを返します。
RANGE BETWEEN ORDER BY 式に NULL 値が含まれる場合の動作¶
RANGE BETWEEN ウィンドウフレームが使用され、 ORDER BY 列が NULL 値を含む場合、以下の動作に注意してください:
ORDER BY 句で NULLS FIRST を指定した場合、 ORDER BY 列に NULL を持つ行は、 UNBOUNDED PRECEDING フレームに含まれます。
ORDER BY 句で NULLS LAST を指定した場合、 ORDER BY 列に NULL を持つ行は、 UNBOUNDED FOLLOWING フレームに含まれます。
ORDER BY 列に NULL を持つ行は、現在の行の ORDER BY 値が NULL である場合にのみ、明示的オフセット枠境界に含まれます。
RANGE BETWEEN ORDER BY 句に NULL の値がある例 をご参照ください。
ウィンドウフレームの使用上の注意¶
一部のウィンドウ関数はウィンドウフレームをサポートしています。ただし、ウィンドウフレーム構文のサポートは機能によって異なります。ウィンドウフレームが指定されていない場合、デフォルトは関数によって異なります。
非ランキング関数( COUNT 、 MAX 、 MIN 、 SUM など)の場合、デフォルトは以下のウィンドウフレーム( ANSI 標準準拠)です。
ランキング関数( FIRST_VALUE、 LAST_VALUE、 NTH_VALUE など)の場合、デフォルトはウィンドウ全体です。
この動作は、 ANSI 標準に 準拠していない ことにご注意ください。
注釈
わかりやすくするために、Snowflakeでは暗黙的なウィンドウフレームを避けることをお勧めします。クエリでウィンドウフレームを使用する場合は、明示的なウィンドウフレームを定義します。
ウィンドウフレームでは、ウィンドウ内のデータが既知の順序であることが必要です。したがって、 ORDER BY 句は一般的なウィンドウ関数構文では任意ですが、 OVER 句内の ORDER BY 句はウィンドウフレーム構文では 必須 です。
例¶
このセクションでは、ウィンドウ関数のさまざまな使い方の例を紹介します。その他の例については、 ウィンドウ関数を使ったデータ分析 および各機能のページをご参照ください。
使用例¶
店舗のチェーンを所有しているとします。次のクエリは、チェーン全体の利益のうち、各店舗が生み出す利益の割合を示しています。クエリは RATIO_TO_REPORT 関数を使用します。この関数は、現在の行から値 (net_profit) を取得し、それを他のすべての行の対応する値の合計(net_profit)で除算します。
テーブルを作成してロードします。
テーブルをクエリします。
開始位置が拘束されないウィンドウフレーム¶
値が含まれるテーブルを作成および生成します。
境界のない開始位置を持つウィンドウ・フレームを使用するクエリを実行し、出力を表示します。各パーティションの各行の累積値の COUNT, SUM, AVG, MIN, MAX を返します:
デフォルトのウィンドウフレームセマンティクス( ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)を使用して、上記のクエリと同じ結果を返します。
明示的なオフセットを持つウィンドウ・フレーム¶
値が含まれるテーブルを作成および生成します。
2つの列(数値と文字列)に対して、現在の行を含むスライディングウィンドウの前後で、 MIN 関数の結果を返します:
2つの列(数値と文字列)に対して、現在の行を含むスライディングウィンドウの前後で、 MAX 関数の結果を返します:
現在の行の前、後、および包括的なスライディングウィンドウ全体の数値列の合計を返します。
ランキング関数の例¶
次の例は、それぞれが販売した合計金額(ドル)に基づいて営業担当者をランク付けする方法を示しています。OVER 句内の ORDER BY 句は、合計を降順(高い順)にソートします。次に、クエリは他の営業担当者に対する各営業担当者のランクを計算します。
まず、テーブルを作成してデータを挿入します。
次に、データをクエリします。
出力は必ずしも順位順ではありません。順位で結果を表示するには、ここに表示されているように(ウィンドウ関数の ORDER BY 句に加えて)クエリ自体に ORDER BY 句を指定します。
先の例には、 ORDER BY 句が 2つ あります:
1つはランキングの順序を制御します。
1つは出力の順序を制御します。
これらの句は独立しています。例えば、総売上に基づいて(上記のように)ランキングを並べ替えることができますが、販売員の姓に基づいて出力行を並べ替えることもできます。
明示的な数値オフセットの RANGE BETWEEN 例¶
次の例では、 RANGE BETWEEN の構文を使用し、オフセットを明示的に数値で指定しています。この例を実行するには、以下の指示に従ってください: menu_itemsテーブルを作成してロードする INTERVAL オフセットを使用した同様の例については、 ローリング計算にウィンドウ集約を使用する をご参照ください。
以下のクエリは、フードトラックで提供されるメニューのカテゴリーについて平均売上原価を計算します。窓関数は結果を分割しない。したがって、平均は、範囲ベースのフレームに従った、完全な結果セット全体にわたって計算されます。
枠の境界は、現在の行の商品価格に2を足したものです(例えば、最初の行=0.50+2.00)。列がこの2ドルの範囲内にあるとき、枠に入る資格があります。
例えば、最初の行の avg_cogs 値は1.1833です。これは、0.50から2.50の間に入るすべての menu_cogs_usd 値の合計を、それらの行の数で割ったものとして計算されます:
(0.50 + 0.65 + 0.75 + 0.50 + 1.00 + 1.25 + 2.50 + 1.25 + 2.25) / 9 = 1.18333
最後から2番目の行のavg_cogsの値は2.93750です。これは、2.25から4.25の間に入るすべての menu_cogs_usd 値の合計を、それらの行の数で割ったものとして計算されます:
(2.25 + 2.50 + 3.00 + 4.00) / 4 = 2.93750
最後の行は、 avg_cogs と menu_cogs_usd の両方で4.0を返しています。この結果が正確なのは、この行だけがフレームに属しているからです。4.0は結果全体における最大値 menu_cogs_usd 、1行のフレームとなります。「以下」の行はありません。
このクエリには、ウィンドウ関数のための ORDER BY 句と、クエリの最終結果のための ORDER BY 句があることにご注意ください。最終的な ORDER BY の出力は、窓関数の結果の計算に影響を与えません。関数を計算するための順序付き結果セットは、最終クエリが表示しない中間結果セットです。
RANGE BETWEEN ORDER BY 句に NULL の値がある例¶
nulls テーブルには5つの行があり、2つは c1 列に NULL があります。テーブルの作成とロードは次のとおりです。
NULLS LAST が指定され、ウィンドウフレームが明示的なオフセットを使用する場合、 c1 に NULL を持つ行は、現在の行の ORDER BY の値が NULL である場合にのみフレームに含まれます。以下のクエリは、 3 行が現在の行である場合、 50 の合計を返します。以下の NULL の行はフレームに含まれません。
NULLS LAST が指定され、ウィンドウ・フレームが UNBOUNDED FOLLOWING を使用する場合、 NULL が c1 に含まれる行がフレームに含まれます。以下のクエリは、 3 行が現在の行である場合、 120 の合計を返します。以下の NULL の両行がフレームに含まれます。
heavy_weatherテーブルの作成とロード¶
heavy_weather テーブル(いくつかのウィンドウ機能の 例 で使用される)を作成し、行を挿入するには、このスクリプトを実行します。