前回はグループ関数を使った集計結果を説明しました。今回も、前回に引き続きグループ関数を使ってデータをさまざまな切り口で分析・集計する方法を紹介します(編集部)
“データベースを企業活動に活用する”という考え方も、最近は一般的になってきました。
例えば、売り上げの目標達成状況を経営会議でディスカッションするために、“本部ごと、部門ごと、さらにチームごとの売り上げをレポート化する”ような、データベースの活用はよく行われています。
また、マーケティングプランを策定するために、“関連する商品をグループ化したり、地域や購買層などの属性と組み合わせて商品の売り上げ傾向を分析したい”というケースもあるでしょう(その裏で、レポートを出力するために、前夜遅くまで残って作業をするシステム担当者もいらっしゃるのではないでしょうか……)。
このように、データベースを利用したレポーティングや、BI(ビジネスインテリジェンス)による分析ニーズは、近年さらに強まっているようです。今回は、そのような場合に役立つ、データのレポート化や集計に役立つ便利な構文をご紹介します。「うちではツールを使っているよ」という方も、ツールの裏でどんなSQL文が実行されているか、興味はありませんか?
連載第9回の実行例でも紹介したとおり、今回使っているEMP表には、社員と、社員が所属する部門、職種が登録されています。今回は、部門、職種の情報を使って、もう少し複雑なグループ化の方法を考えてみましょう。
ここでは、次のような処理を考えてみます。
人事部では、社員の平均給与(およびその計算対象となる人数)を、「全社員」「部門別」「部門内職種別」の3段階で集計したレポートを作成することになりました。この場合には、どのようなSQL文を書けばよいでしょうか。
一度に書こうと考えると難しいので、必要な情報を得るための手順を、次のように分割して考えてみましょう。
全社員を部門別および職種別でグループ化し、各グループの人数と平均給与を求める(部門内職種別)
全社員を部門別でグループ化し、各グループの人数と平均給与を求める(部門別)
全社員の人数と平均給与を求める(全社員)
この3つの集計結果をひとつにまとめれば、要件に合う結果が得られそうです。
上記(1)〜(3)の結果を求めるSQL文は、前回までの知識で、次のように書くことができますね。
(1)全社員を部門別および職種別でグループ化し、各グループの人数と平均給与を求める
SELECT deptno, job, COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" x FROM emp GROUP BY deptno, job;
(2)全社員を部門別でグループ化し、各グループの人数と平均給与を求める
SELECT deptno, COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" FROM emp GROUP BY deptno;
(3)全社員の人数と平均給与を求める
SELECT COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" FROM emp;
(1)〜(3)のSQL文を別々に実行すると、当然ながら結果は別々に表示されます。しかし今回は、結果をレポートのようにひとつにまとめて表示したいのです。何か良い方法はないでしょうか?
このような場合に、SQLのUNION演算子を使うと、別々に記述した複数のSQL文の結果をひとつにまとめて表示することができます。UNION演算子は、複数のSELECT文をつなぐ形で、次のように指定します。
SELECT deptno, job, COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" FROM emp GROUP BY deptno, job UNION SELECT deptno, null, COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" FROM emp GROUP BY deptno UNION SELECT null, null, COUNT(*) AS "社員数",TRUNC(AVG(sal)) AS "平均給与" FROM emp;
UNION演算子を使う際には、注意が必要です。それは、UNIONで連結する各SQL文の、SELECT句の列数とデータ型が同じでなければならないということです。
この例では、(1)のSQL文では4列(deptno、job,社員数、合計給与)、(2)のSQL文では3列(deptno、社員数、合計給与)、(3)のSQL文では2列 (社員数、合計給与)と、SELECT句で指定している列数が異なっています。そこで、(2)と(3)のSELECT句にはNULLを指定して、4列ずつになるように調整しています。
Copyright © ITmedia, Inc. All Rights Reserved.