ゼロベース独学SQL講座 | ウィンドウ関数

皆さんこんにちは、私の名前はニンイーです。

今日はレッスン 24: ウィンドウ関数です。

ウィンドウ関数は OLAP (オンライン分析処理) とも呼ばれ、データベース データのリアルタイム分析と処理を実行できます。

ウィンドウ関数はデータアナリストがよく使う構文関数で、大手企業の面接ではほぼ必須の質問となります。

このセクションは高度な内容であり、理解するのが難しいため、効果を確認するにはコンピュータに入力する必要があります。

そうすることでのみ、理解が深まるのです。前回のコースではデータベースのインストール方法を説明しましたが、私のホームページで確認できます~

基本的な文法

<窗口函数> OVER (
[PARTITION BY <用于分组的列名>] -- 可选
[ORDER BY <用于排序的列名>] -- 可选
)

上記の <window function> の位置には、次の 2 つの関数を配置できます。

(1) 集計関数: sum.avg、count、max、min など。

(2) 特別なウィンドウ関数: Rank、dense_rank、row_number など。これについては以下で詳しく説明します。

通常、ウィンドウ関数は select ステートメントに配置されます。

1. 集計機能

ウィンドウ関数はグループ化と並べ替えにも使用され、集計関数 + GROUP BY と同様の効果があります。ただし、ウィンドウ関数によって生成されたレコードは集約されず、データ行ごとに 1 つのレコードが生成されます。

例: [スコア] テーブルで、ID が 7 ~ 10 の生徒を検索し、各生徒の合計スコアを計算して表示します。

SELECT
  Sid,
  SUM(score) AS "总分"
FROM Scores
WHERE Sid BETWEEN 7 AND 10
GROUP BY Sid;

しかし、ここで問題が発生します。生徒の合計スコアはわかりますが、各科目の具体的なスコアも知りたいのです。これは、上記のステートメントを使用して行うことはできません。

なぜ?

SELECT の後のフィールドがテーブル内の既存の列である場合、この列も GROUP BY 句に含める必要があるためです。

したがって、各科目の具体的なスコアを知りたい場合は、SELECT の後に Cid とスコアの 2 つの列を追加する必要があります。これらの 2 つの列を GROUP BY 句に追加すると、トピックに反します。

この知識点については、講義 15 と 16 で強調しました。ホームページをクリックして詳細を学ぶことができますが、ここでは詳しく説明しません。

同僚に学生の合計スコア、コース番号、スコアを知らせたい場合は、ウィンドウ関数を使用する必要があります。

SELECT
  Sid,Cid,score,
  SUM(score) OVER (PARTITION BY Sid) AS "总分"
FROM Scores
WHERE Sid BETWEEN 7 AND 10;

補足知識:PARTITION BYの意味

PARTITION BY はパーティションを意味し、GROUP BY と同様です。

PARTITION BY が記述されていない場合は、データ セット全体が 1 つのパーティションに属していることを意味します。

たとえば、上記の SQL ステートメントで PARTITION BY が省略された場合、

SELECT
  Sid,Cid,score,
  SUM(score) OVER() AS "总分"
FROM Scores
WHERE Sid BETWEEN 7 AND 10;

結果は以下のようになり、生徒全員の合計点が計算されます。

2. 特殊なウィンドウ機能

一般的に使用される特別なウィンドウ関数は次のとおりです。

(1) データランキングの取得:

ROW_NUMBER():同順位のランキングは考慮されません。たとえば、上位 3 つのスコアはすべて 88、88、77 であり、ランキングは 1、2、3 になります。

RANK():ランキングが同点の行がある場合、それらは次にランク付けされた位置を占めます。たとえば、上位 3 つのスコアはすべて 88、88、77 であり、順位は 1、1、3 になります。

DEBSE_RANK():ランク付けされた行が同点の場合、それらは次にランク付けされた位置を占めません。たとえば、上位 3 つのスコアはすべて 88、88、77 であり、順位は 1、1、2 になります。

例:スコア表で、ID が 7 ~ 10 の生徒を検索し、上位から下位までのランキングを計算します。

SELECT *,
  ROW_NUMBER() OVER(
    ORDER BY score DESC
  ) AS "排名"
FROM Scores
WHERE Sid BETWEEN 7 AND 10;

上記では ROW_NUMBER() ウィンドウ関数が使用されており、「Ranking」列が追加されていることがわかります。ROW_NUMBER() を RANK() に置き換えると、戻り結果は次のようになります。

(2) 最初または最後の場所を取得します。

FIRST_VALUE(<列名>) : 1 位を取得します。

LAST_VALUE(<列名>) : 最後の値を取得します。

例:スコア表で、ID が 7 ~ 10 の生徒を検索し、各生徒の最高スコアを取得します。

SELECT *,
  FIRST_VALUE(score) OVER(
    PARTITION BY Sid
    ORDER BY score DESC
  ) AS "最高成绩"
FROM Scores
WHERE Sid BETWEEN 7 AND 10;

(3) オフセット機能:

LEAD(<列名>,<値 n>) : 現在の行から n 行下方向のデータ オフセットにアクセスします。

LAG(<列名>,<値 n>) : 現在の行から n 行のデータ オフセットにアクセスします。

NTH_VALUE(<列名>,<値 n>) : 結果セットの N 行目からデータを取得します。

(4) 分配関数:

CUME_DIST() : 現在のランク値/グループ内の合計行数以下のグループ内の行数。

PERCENT_RANK() : 列の各行のランキングのパーセンテージを返します。各行は、式 (rank-1) / (rows-1) に従って計算されます。

NTILE(<Number n>) : 結果セット全体を n 個のグループに分割し、特定のデータがどのグループに割り当てられているかを示します。

宿題:スコアのオフセット関数と分布関数を検証し、どのような結果が返されるかを確認します。

例:以下の行 2 のオフセット スコアを取得します。

SELECT *,
  LEAD(score,2) OVER(
    ORDER BY score DESC
  ) AS "获取下面第2行score值"
FROM Scores
WHERE Sid BETWEEN 7 AND 10;

SQL の入門コースから上級コースまでが終了しました。今後も、ビュー、インデックス、同時実行性、デッドロック、トリガー、イベント、トランザクション、ストアド プロシージャなどを含む高度な SQL コースを公開し続ける予定です。

録画授業とライブ授業も続きます~

おすすめ

転載: blog.csdn.net/shine_a/article/details/125528974