logo

SQLのウィンドウ関数

ウィンドウ関数は、特定のウィンドウ (行のセット) にわたる集計関数とランキング関数に適用されます。 OVER 句は、ウィンドウ関数とともに使用して、そのウィンドウを定義します。 OVER 句は次の 2 つのことを行います。

  • 行を分割して行のセットを形成します。 (PARTITION BY句を使用します)
  • これらのパーティション内の行を特定の順序に並べます。 (ORDER BY句を使用します)

注記: パーティションが完了していない場合は、ORDER BY によってテーブルのすべての行が順序付けされます。



構文:

乱数生成Java
SELECT coulmn_name1,   window_function(cloumn_name2)  OVER([PARTITION BY column_name1] [ORDER BY column_name3]) AS new_column FROM table_name;       window_function=   any aggregate or ranking function    column_name1  = column to be selected   coulmn_name2=   column on which window function is to be applied   column_name3  = column on whose basis partition of rows is to be done   new_column=   Name of new column   table_name=   Name of table>

集計ウィンドウ関数
特定のウィンドウ (行のセット) に適用される SUM()、COUNT()、AVERAGE()、MAX()、MIN() などのさまざまな集計関数は、集計ウィンドウ関数と呼ばれます。

次のことを考慮してください 従業員 テーブル :



名前 部門 給料
ラメッシュ 二十 ファイナンス 50,000
深い 25 販売 30,000
スレシュ 22 ファイナンス 50000
ラム 28 ファイナンス 20,000
プラディープ 22 販売 20,000

例 -
各部門の従業員の平均給与を調べ、部門内の従業員を年齢順に並べます。

SELECT Name, Age, Department, Salary,   AVG(Salary) OVER( PARTITION BY Department) AS Avg_Salary  FROM employee>

これにより、次が出力されます。

名前 部門 給料 平均給与
ラメッシュ 二十 ファイナンス 50,000 40,000
スレシュ 22 ファイナンス 50,000 40,000
ラム 28 ファイナンス 20,000 40,000
深い 25 販売 30,000 25,000
プラディープ 22 販売 20,000 25,000

特定のウィンドウ内のすべての平均給与が同じ値であることに注目してください。



別のケースを考えてみましょう。

SELECT Name, Age, Department, Salary,   AVG(Salary) OVER( PARTITION BY Department ORDER BY Age) AS Avg_Salary  FROM employee>

ここでは、パーティション内のレコードを年齢値に従って並べ替えているため、平均値は並べ替えられた順序に従って変化します。
上記のクエリの出力は次のようになります。

Java数学ランダム
名前 部門 給料 平均給与
ラメッシュ 二十 ファイナンス 50,000 50,000
スレシュ 22 ファイナンス 50,000 50,000
ラム 28 ファイナンス 20,000 40,000
プラディープ 22 販売 20,000 20,000
深い 25 販売 30,000 25,000

したがって、集計を含むウィンドウ関数に order by 句を追加するときは注意が必要です。

ランキングウィンドウの機能:
ランキング関数は、RANK()、DENSE_RANK()、ROW_NUMBER() です。

  • ランク() –
    名前が示すように、ランク関数は各パーティション内のすべての行にランクを割り当てます。ランクは、先頭行にランク1を与え、それ以降は同じ値を持つ行には同じランクが与えられる。 2 つの同じランク値の後の次のランクでは、1 つのランク値がスキップされます。たとえば、2 つの行がランク 1 を共有している場合、次の行はランク 2 ではなく 3 になります。
  • DENSE_RANK() –
    パーティション内の各行にランクを割り当てます。ランク関数と同様に、最初の行にはランク 1 が割り当てられ、同じ値を持つ行は同じランクになります。 RANK() と DENSE_RANK() の違いは、DENSE_RANK() では、2 つの同じランクの後の次のランクには連続する整数が使用され、ランクはスキップされないことです。
  • ROW_NUMBER() –
    ROW_NUMBER() は各行に一意の番号を与えます。行に 1 から合計行まで番号を付けます。行は、その値に基づいてグループに分類されます。各グループはパーティションと呼ばれます。各パーティションでは、行に順番に番号が付けられます。パーティション内に同じ番号を持つ 2 つの行はありません。これにより、ROW_NUMBER() は RANK() および DENSE_RANK() とは異なります。 ROW_NUMBER() は、連続した整数ですべての行を一意に識別します。これは、さまざまな種類のデータ分析に役立ちます。

注記 -
ランクウィンドウ関数を使用する場合は、ORDER BY()を強制的に指定する必要があります。

例 -
各部門内の給与に応じた従業員テーブルの行番号、順位、密順位を計算します。

SELECT   ROW_NUMBER() OVER (PARTITION BY Department ORDER BY Salary DESC) AS emp_row_no,   Name,   Department,   Salary,  RANK() OVER(PARTITION BY Department ORDER BY Salary DESC) AS emp_rank,  DENSE_RANK() OVER(PARTITION BY Department ORDER BY Salary DESC) AS emp_dense_rank FROM   employee;>

上記のクエリの出力は次のようになります。

アンドロイドプロセスアコア
emp_row_no 名前 部門 給料 emp_rank emp_dense_rank
1 ラメッシュ ファイナンス 50,000 1 1
2 スレシュ ファイナンス 50,000 1 1
3 ラム ファイナンス 20,000 3 2
1 深い 販売 30,000 1 1
2 プラディープ 販売 20,000 2 2

したがって、ROW_NUMBER() の定義で述べたように、行番号は各パーティション内の連続する整数であることがわかります。また、ランクと密ランクの違いは、密ランクではランク値間にギャップがないのに対し、ランクを繰り返すとランク値にギャップが生じることがわかります。