高度な SQL 分析関数 - ウィンドウ関数

序文

SQL ステートメントでは、集計関数は、各ビジネス分野のビジネスの総数、各クラスの学生の平均スコア、各カテゴリの最大値の計算など、ビジネス データの結果の統計において重要な役割を果たします。ただし、今日はウィンドウ関数を紹介します。これも集計関数と比較すると関数のセットですが、使用方法と適用可能な場合が異なります。この章では、ウィンドウ関数の RANK 関数と DENSE_RANK 関数、およびランキングとフィルタリングにおけるそれらのアプリケーション シナリオに焦点を当てます。これらのウィンドウ関数は、データをより柔軟に処理し、望ましい結果を得るのに役立ちます。現在の主流のデータベースに最低限必要なウィンドウ関数のバージョンは次のとおりであることに注意してください。

Mysql (>=8.0)
PostgreSQL(>=8.4)
SQL Server(>2005)
SQLite(>3.25.0)

データベースのバージョンが上記の要件より低い場合、ウィンドウ関数は使用できません。

需要の背景:

誰もがよりよく理解できるように、クエリの条件付き背景として学生データを使用します。特定の学校の特定の学年の学生が試験を完了し、その結果もデータベースに入力されていると仮定します。

さて、学年主任は次のことを確認したいと考えています。

1. この試験におけるこの学年の各科目の上位 2 人の生徒。

2. この試験の各クラスの各科目の上位 2 名。

3. このテストの各クラスの合計点で上位 2 位を順位付けします。

通常のSQLでクエリを実行すると面倒で時間もかかりますが、RANK関数とDENSE_RANK関数を使用することで、目的の生徒データを素早くクエリすることができます。学生データの。

PolyRANK 関数と DENSE_RANK 関数を使用した生徒データのクエリ

1. この学年の各科目の上位 2 人の生徒をクエリします。

異なる科目ごとに上位 2 位を取得するには、Rank() 関数を使用して、それぞれの科目部門で各学生をランク付けする必要があります。次の SQL ステートメントを実行すると、クエリの結果は次の図に示すようになります。

select sd.*, RANK() over(スコア記述による科目順で分割) as _rank from core_data sd;

実行結果の各被験者の結果に応じて、ランキングフィールド _rank が取得されていることがわかります。次に、_rank フィールドが 2 より大きい部分をフィルタリングするだけです。クエリ結果は図に示されています。下に。

select * from (

select sd.*, RANK() over(partition by subject order by score desc) as _rank from score_data sd

) tmp

where tmp._rank <=2

上図より、同じ成績があれば数学科目のようなクエリ結果が得られます。数学クエリからは3つの値が得られます(数学の点数が同じ77点の人が2人いるため) , 繰り返しデータの一部を保持したいだけの場合は、DENSE_RANK 関数を使用できます。この関数の計算構文は基本的に RANK の計算構文と同じです。唯一の違いは、ランクを計算するときに合計を取得することです。現在の行よりも高いスコアを持つ行の数 (上図のクエリです。数学科目の 3 つのデータ)、および DENSE_RANK は、現在の行よりも高いスコアを持つ重複排除されたレコードの総数を計算します。つまり、上の図のように数学科目に重複データがある場合、重複データは削除されます。

2. 各クラスの各科目の上位 2 つをクエリします。

各クラスの各教科の上位 2 人をクエリするには、最初のステップでクラス パーティション ルールを追加するだけです (この学年の各教科の上位 2 人の生徒をクエリします)。クエリの結果は次の図に示されています。 :

select * from (

select sd.*, RANK() over(partition by subject, class order by score desc) as _rank from score_data sd

) tmp

where tmp._rank <=2

3. 各クラスの上位 2 つの合計スコアをクエリします。

同様に、2 番目のステップ (score_data テーブルの各クラスの各科目の上位 2 をクエリ) に基づいて、成績の合計 SUM(score) 関数を追加して、各クラスの合計スコアの上位 2 をクエリします。

select class,name,SUM(score) AS total_score,

RANK() over (PARTITION by class order by SUM(score) desc)

from score_data sd group by class,name

SQL コピー全画面表示


この指標の計算では、各人の合計得点が複数の科目の合計に分割されるため、クラスとクラスの共同グループ化の次元で集計する必要があるため、集計関数とランキング関数を組み合わせる必要があります。被験者ごとにデータを結合し、1 人あたりの合計スコアの粒度に圧縮します。

要約する

ウィンドウ関数は、特にレポート統計やその他のシナリオの分野において、SQL 関数の非常に強力なツールです。複雑なデータの計算と分析を簡素化できるだけでなく、クエリの効率と柔軟性も向上します。ウィンドウ関数はデータベース操作における最も鋭いスイス アーミー ナイフのようなもので、データを処理するための強力かつ正確な方法を提供します。

おすすめ

転載: blog.csdn.net/weixin_45925028/article/details/132336930