【参考リンク】https://zhuanlan.zhihu.com/p/98655285
mysql8.0以降のウィンドウ関数
ウィンドウ関数はOLAP関数(Online Analytical Processing)とも呼ばれます。
1. ウィンドウ関数の文法構造:
#キーワード : 分割と順序付け
<ウィンドウ関数> over ([PARTITION by <列リスト>]
Order by <並べ替え用の列のリスト> )
ウィンドウ関数には次の 2 種類があります。
a. ウィンドウ関数として使用できる集計関数: (sum、avg、count、max、min)
b. 特別なウィンドウ関数: (Rank、Dense_Rank、Row_Number)
【1】グループランキング効果の実現
[2] 2 つの質問。1 つは最高スコアの顧客を選択するもの、もう 1 つは各ユーザーの最高スコアを選択するもの
2. 専用ウィンドウ機能の利用
a) 使用方法
Rank 関数はソート順序を記録する関数です。partition by は結果セットをグループ化するために使用されます。指定されていない場合は、結果セット全体をグループとして扱います。集計関数や groupby との違いは次のとおりです。グループ レコード内の複数の項目を返すことができ、集計関数には通常、統計値を反映するレコードが 1 つだけあります。
-- 查看表
SELECT * FROM product;
-- テーブル内の 8 種類の商品を、シリアル番号に応じて、product_type と sale_price に従って並べます。
# ステートメント内の PARTITION By は、ソートするオブジェクトの範囲 (テーブルを水平方向にグループ化) を指定します。
# order by は、配置する列と順序を指定します (並べ替えルールを垂直方向に定義します)。
-- 指定partition by 的字段
SELECT product_id,product_name,product_type,sale_price,
rank() over (PARTITION BY product_type ORDER BY sale_price ASC ) as '排序'
FROM product
-- PARTITION By がないとどうなるでしょうか?
# PARTITION By 関数グループをサイレント項目として設定します
select product_id,product_name,product_type,sale_price,
rank() over (order by sale_price asc) as '排序'
from product
結果は以下の通りです。 1) データ表示はグループ化されず、sale_price で直接ソートされます。
2) 価格が同点の場合、ソート結果は一貫しており、ソートカウント値は +1 になります。
b) 機能の違い
上記の専用ウィンドウ関数には Rank、Dense_Rank、Row_Number の 3 種類がありますが、これら 3 つの違いは何ですか?
# 以下の 3 つの関数のソート結果をソート 1、ソート 2、ソート 3 として定義し、結果を出力します。
select product_id,product_name,product_type,sale_price,
rank() over (order by sale_price asc) as '排序1',
dense_rank() over (order by sale_price asc) as '排序2',
row_number() over (order by sale_price asc) as '排序3'
from product
ソート 1 とソート 2 を比較すると、dense_rank 関数が並置結果を計算するとき、並置値は場所を占めておらず、3 位が 2 つ連続する場合でも、その後のカウント結果は 4 のままであることがわかります。
ソート 2 とソート 3 を比較すると、row-number は sale_price 値が一貫しているかどうかに関係なく一意の値を計算し、連続値を計算しないことがわかります。
c) ウィンドウ関数としての集計関数
(sum、avg、count、max、min) などの集計関数は、ウィンドウ関数から参照できます。
#sum 集計関数の使用
select product_id,product_name,product_type,sale_price,
sum(sale_price) over (order by product_id) as '累加'
from product
上記結果を累積すると、sale_priceが累積され、ソート1で上記結果の累積和が計算されていることが分かります。テーブル内のデータはproduct_id順に並べられており、同様にAVG関数累積値の平均値を計算します。
ヒント: 集計関数はウィンドウ関数として使用されますが、並べ替えほど単純ではなく、累積したり、累積して平均したりする場合があります。
d) ソート結果の順序を保証する
上記の結果に従って並べ替えると、並べ替え結果が順序付けされていない場合がありますが、double order by を使用して順番に並べ替えることができます。
# 計算結果を並べ直す
select product_id,product_name,product_type,sale_price,
rank() over (order by sale_price ) as '排序1'
from product
order by 排序1 desc
-- 按 product_type 统计总金额,及其各产品金额占比
-- 按 product_type 统计金额由小到大进行累计,
SELECT product_id, product_name, product_type, sale_price
, sum(sale_price) over(PARTITION BY product_type) as typeSum
, sale_price / sum(sale_price) over(PARTITION BY product_type) as ratioInType
, sum(sale_price) over(PARTITION BY product_type ORDER BY sale_price) as orderCumsum
FROM product ORDER BY product_type, sale_price;