Blog

GROUPING SETSで効率よくクエリを書く

はじめに

インフラシステムグループの河野です。 最近集計・分析系のクエリを書く機会が多くなっています。
その中でGROUPING SETSに出会って感動したのでこの気持を分かち合いたいと思います。 記事中ではクエリエンジンとしてpresto 0.217を使用しています。

GROUPING SETSとは

GROUPING SETSはGROUP BY句に付与する構文で、複雑なGROUP BYを実現するときに使用できます。 具体例を見ていきましょう。例えば、以下のようなstockテーブルを考えます。店舗ごとにフルーツの在庫がいくつあるか、値段はいくらなのかをまとめたテーブルです。 商品ごとの合計を出しつつ、全体の合計も出したいときが来たとします。この場合GROUPING SETSを使わないとすると以下のようなクエリで実現できます。 これをGROUPING SETSで書き換えると以下のようになります。 このように複数の基準でGROUP BYしなければならないものを、GROUPING SETSで一つにまとめることができます。
実務ではクラウドコストを集計してグラフ表示するときに非常に役に立ちました。クラウドベンダごとに別のグラフを描く。合計値も同時に描画したい。といった要件が出てきて、はじめは愚直にUNIONしていて、30行程度のクエリになっていました。その後prestoのリファレンスを見ていたらGROUPING SETSを見つけたので試しに書き換えてみたら、15行ほどにすっきりとクエリを書き替えることができました。

ROLLUP、CUBEとの関係性

GROUPING SETSと似た構文にROLLUPとCUBEがあります。ROLLUPでは小計、総計をまとめて取得することができます。CUBEではすべての組み合わせに対して総計を取得することができます。
それぞれ先程のstockテーブルに対して適用した結果を見てみましょう。
ROLLUP: CUBE: これらをGROUPING SETSで書き換えると以下のようになります。
ROLLUP → GROUPING SETS: CUBE → GROUPING SETS: それぞれの差分だけ見るとどういう動きをしているかわかりやすいと思います。 例えば、組み合わせが一個増えたときの対応はこうなります。ROLLUPでは一番左のカラムを基準としたときの組み合わせ、CUBEではすべての組み合わせをそれぞれグルーピングしています。 GROUPING SETSで書くことで、どの組み合わせで集計しているのかがわかりやすくなるため、個人的にこの書き方が好みです。

終わりに

今回はGROUPING SETSについて使い方と、他の類似構文との関連性をまとめました。有効に使えるとクエリをすっきりとさせられるので機会があれば使ってみてください。

参考記事

https://prestodb.io/docs/0.217/sql/select.html

We are hiring!

ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! Tech TalkやMeetUpも開催しております!
こちらもお気軽にご応募ください!