データをグループ化して表示してみよう(2):Webブラウザで気軽に学ぶ実践SQL講座(10)(3/3 ページ)
前回はグループ関数を使った集計結果を説明しました。今回も、前回に引き続きグループ関数を使ってデータをさまざまな切り口で分析・集計する方法を紹介します(編集部)
GROUP BYの拡張機能 GROUPING SETS
CUBEを使うと、指定したすべての列の組み合わせに対してクロス集計値を出すことができます。しかし、集計する要素が多い場合は、組み合わせの数も非常に大きくなります。
例えば、集計要素として5列を指定すると、CUBEによる組み合わせの数は全部で 32通り(25)となります。ここまで増えてしまうと、すべての組み合わせを表示するのではなく、必要な集計結果だけに制限したい場合には、使いにくいかもしれません。
このような場合には、GROUPING SETS句を利用します。GROUPING SETSを使用すると、作成するグループの集合を指定して絞り込めます。
SELECT グループ化する列名, 関数 (列名), … FROM 表名 GROUP BY GROUPING SETS ((グループ化したい列のセット1), (グループ化したい列のセット2),…) ・・・
例えば、集計を 「入社年と部門でグループした結果」と、「入社年と職種でグループ化した結果」で行いたい場合は、「GROUPING SETS((入社年,部門),(入社年,職種))」のように指定します。グループ化したい列の組み合わせを指定すればよいので、シンプルに記述することができますね。
それでは、試してみましょう。入社年は、連載第6回で紹介したEXTRACT関数を使って、入社日(hiredate)からyear要素を取り出せば調べることができます。
SELECT EXTRACT(year from hiredate) AS "入社年", deptno, job, COUNT(*) AS 社員数,TRUNC(AVG(sal)) AS "平均給与" FROM emp GROUP BY GROUPING SETS((deptno,EXTRACT(year from hiredate)), (job, EXTRACT(year from hiredate)) );
このように、「入社年と部門でグループした結果(1)」と、「入社年と職種でグループ化した結果(2)」だけが表示されました。
コラム
今回の連載では、部門内の職種ごと、部門ごと、さらに社員全体の人数と平均給与を調べるSQLとして、UNIONを使った方法(図1)とROLLUPを使った方法(図2)をご紹介しました。どちらも同じ実行結果になりますが、見た目のシンプルさ、実行の効率性から、ROLLUPを使った方法をお勧めします。
それでは、それぞれの内部的な実行方法を見てみましょう。連載第4回でも紹介した通り、結果の右にある「実行計画」のタブから、SQL文の実行計画(Oracle Databaseの内部的な実行手順)を確認できます。
(図5)の実行計画を見ると、Oracle Databaseの内部的にも、3つのSQL文が別々に実行されていることが分かります。それに対して(図6)の実行計画では、1回の実行で結果が得られることが分かります。
それぞれの「コスト」を比較してみても、UNIONを使ったSQL文の方が約3倍のコストが掛かっていますね。このように、実行効率から考えても、UNIONを使った方法より、ROLLUPやCUBEを使った方が良いと言えます。
- SQLでデータを操作する(副問合せを利用したINSERT/相関UPDATE/MERGE)
- SQLでデータを操作するときの文法(INSERT/UPDATE/DELETE)
- 高度な副問合せの構文
- 副問合せを使った複雑な条件指定
- データをグループ化して表示してみよう(2)
- データをグループ化して表示してみよう(1)
- 複数の表からデータを取り出して表示させる(2)
- 複数の表からデータを取り出して表示させる(1)
- SQL関数を使って面倒な処理を簡単に済ませる
- SELECT文で取り出したデータを加工して表示する
- 複数の条件を指定してSELECT文を実行する
- まずはここから! 基本的なSELECT文から始めよう
- SQL実行環境を準備しよう
- SQLとはどういう言語か
Copyright © ITmedia, Inc. All Rights Reserved.