範囲を集計する
SELECT句のCASE式で範囲を指定していただき、それをGROUP BYで指定すれば範囲での集計をすることが可能です。これを「パーテーションカット」と呼びます。
書き方
ただ、この書き方はシンプルなのですが、標準違反にはなります。
1 2 3 4 5 6 |
select CASE WHEN age < 20 THEN '子供' WHEN age BETWEEN 20 AND 69 THEN '成人' WHEN age >= 70 THEN '老人' ELSE NULL END AS 年代,count(*) as 人数 from Persons GROUP BY 年代 |
なお、以下の内容と等価になります。以下の書き方がSQL標準での書き方になります。
1 2 3 4 5 6 7 8 9 |
select CASE WHEN age < 20 THEN '子供' WHEN age BETWEEN 20 AND 69 THEN '成人' WHEN age >= 70 THEN '老人' ELSE NULL END AS 年代,count(*) as 人数 from Persons GROUP BY CASE WHEN age < 20 THEN '子供' WHEN age BETWEEN 20 AND 69 THEN '成人' WHEN age >= 70 THEN '老人' ELSE NULL END; |
GROUP BY句には列名だけを指定するものと認識している人が多いのですが、CASE式を利用した範囲を使用することで範囲での集計が可能になるテクニックになります。
パーテーションカットは実行計画には影響する?
GROUP BYでCASE式を使っても普通にGROUP BYを使う場合の実行計画になり特に影響はしないです。もちろん、若干CASE式の演算は発生するので通常のGROUP BYに比べたらCPU演算のオーバーヘッドは発生するのですが、実行計画のアクセスパスには全く影響はないのでパーテーションカットはパフォーマンスにはほとんど影響はないと見て良いです。
PARTITION BY句と比べたらどうか
ウインドウ関数にPARTITION BYという機能があると思います。機能的には違いはないです。ただ、集約はしないのでそのままの結果が出てきたりしますし、そもそもRDBMSのバージョンによってはウインドウ関数が対応していないので注意です。
この記事へのコメントはありません。