-- OVER () のカッコを空にすると、対象は結果セット全体-- 5 行の明細はそのまま 5 行残り、grand_total 列に全行同じ値が並ぶSELECT sale_id, emp_id, amount,SUM(amount) OVER () AS grand_total,COUNT(*) OVER () AS row_count,AVG(amount) OVER () AS grand_avgFROM sales;
① まずGROUP BY版として、emp_id = 2 の売上を社員単位で集計してください。salesからemp_id = 2の行を絞り、emp_id、COUNT(*) AS cnt、SUM(amount) AS totalの 3 列を取り出し、GROUP BY emp_idで集計します。1 行に畳まれる動きを確認します。
② 続けてウィンドウ関数版として、同じemp_id = 2の売上明細を残したまま、SUM(amount) OVER () AS grand_totalを付けてください。sale_id、emp_id、amount、grand_totalの 4 列を取り出します。5 行のままで、各行に同じ合計値が並びます。
③ 2 つのクエリを 1 つのコンソールに並べて実行 し、結果が 「1 行」 vs 「5 行」 で異なることを目で確かめてください。判定はウィンドウ関数側の結果を見るため、ORDER BY sale_idで並びを固定します。
SQL エディタ
クエリを実行してください
スキーマ
テーブルがありません
PARTITION BY — ウィンドウを「グループごと」に区切る
OVER ()は結果全体が 1 つのウィンドウ(集計対象範囲)でしたが、OVER (PARTITION BY 列)と書くと、その列の値ごとにウィンドウを区切って集計します。
PARTITION BY emp_idなら「社員ごと」にウィンドウが分かれ、各行にはその行が属する社員の合計が計算されます。
-- 社員ごとの合計・平均・件数を、明細を残したまま各行に付けるSELECT sale_id, emp_id, amount,SUM(amount) OVER (PARTITIONBY emp_id) AS emp_total,AVG(amount) OVER (PARTITIONBY emp_id) AS emp_avg,COUNT(*) OVER (PARTITIONBY emp_id) AS emp_countFROM salesORDER BY emp_id, sale_id;-- 構成比: その明細が「その社員の合計」の何 % かSELECT sale_id, emp_id, amount, amount * 100.0 / SUM(amount) OVER (PARTITIONBY emp_id) AS pct_of_empFROM salesORDER BY emp_id, sale_id;
-- sales を employee と JOIN し、部署ごとの売上合計・件数を各明細に付けるSELECTs.sale_id, e.name, e.dept_id, s.amount,SUM(s.amount) OVER (PARTITIONBYe.dept_id) AS dept_total,COUNT(*) OVER (PARTITIONBYe.dept_id) AS dept_salesFROM sales AS sJOIN employee AS e ONs.emp_id=e.emp_idORDER BYe.dept_id, s.sale_id;
Q1ウィンドウ関数(集計関数(...) OVER (...))とGROUP BY集計の違いとして正しいものはどれですか。
Q2SUM(amount) OVER ()のようにOVERのカッコを空にしたときの集計対象はどれですか。
Q3SELECT s.amount, SUM(s.amount) OVER (PARTITION BY e.dept_id) FROM sales s JOIN employee e ON s.emp_id = e.emp_id;のPARTITION BY e.dept_idの説明として正しいものはどれですか。