SQL Serverで中央値を計算する
SQL Server には MEDIAN() 関数がありません。最も近いのは PERCENTILE_CONT() で、データセットの n 番目のパーセンタイルにある値を求めます。
インシデントのロールアップセットで、事故タイプごとに中央値が平均からどれくらい離れているかを確認したいとします。これには、前の演習で使った AVG() と PERCENTILE_CONT() を比較します。これらはウィンドウ関数で、詳しくは第4章で扱います。ここでは、PERCENTILE_CONT() はパーセンタイル(0 から 1 の小数)を引数に取ることを覚えておいてください。パーセンタイルは WITHIN GROUP 句内の順序付けられたグループに対して計算され、データを分割する必要がある場合は特定の範囲に OVER して適用します。WITHIN GROUP では、50パーセンタイルを求めたい列を基準に並べ替える必要があります。
この演習はコースの一部です
SQL Serverで学ぶ時系列分析
演習の手順
PERCENTILE_CONT()の不足している値を埋めてください。WITHIN GROUP()句の中では、インシデント数を降順で並べ替えます。OVER()句では、IncidentType(ID ではなく実際の文字列の値)でパーティション分割します。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
SELECT DISTINCT
it.IncidentType,
AVG(CAST(ir.NumberOfIncidents AS DECIMAL(4,2)))
OVER(PARTITION BY it.IncidentType) AS MeanNumberOfIncidents,
--- Fill in the missing value
PERCENTILE_CONT(___)
-- Inside our group, order by number of incidents DESC
WITHIN GROUP (ORDER BY ir.___ DESC)
-- Do this for each IncidentType value
OVER (PARTITION BY it.___) AS MedianNumberOfIncidents,
COUNT(1) OVER (PARTITION BY it.IncidentType) AS NumberOfRows
FROM dbo.IncidentRollup ir
INNER JOIN dbo.IncidentType it
ON ir.IncidentTypeID = it.IncidentTypeID
INNER JOIN dbo.Calendar c
ON ir.IncidentDate = c.Date
WHERE
c.CalendarQuarter = 2
AND c.CalendarYear = 2020;