-GROUP BYはデータを条件付きのグループとして設定できる
-設定するグループのコラム名をSELECTとGROUP BYの後に追加すれば良い
--部署別の社員数検索 SQL> SELECT '2013年' year, deptno 部署番号, count(*) 社員数 2 FROM emp 3 GROUP BY deptno 4 ORDER BY COUNT(*) DESC; YEAR 部署番号 社員数 ------ ---------- ---------- 2013年 30 5 2013年 20 5 2013年 10 3
下記例は部署別にグループ化し、部署番号、人数、給与の平均、給与の合計を検索
SQL> SELECT deptno, COUNT(*), ROUND(AVG(sal)) "給与平均", 2 ROUND(SUM(sal)) "給与合計" 3 FROM emp 4 GROUP BY deptno; DEPTNO COUNT(*) 給与平均 給与合計 ---------- ---------- ---------- ---------- 30 5 1630 8150 20 5 2175 10875 10 3 2917 8750
下記例は業務別にグループ化して業務、人数、平均給与、最高給与、最低給与、合計を検索
SQL> SELECT job "業務", COUNT(empno) "人数", ROUND(AVG(sal),1) "平均給与", 2 MAX(sal) "最高給与", MIN(sal) "最低給与", 3 SUM(sal) "給与合計" 4 FROM emp 5 GROUP BY job; 業務 人数 平均給与 最高給与 最低給与 給与合計 --------- ---------- ---------- ---------- ---------- ---------- CLERK 4 1037.5 1300 800 4150 SALESMAN 3 1450 1600 1250 4350 PRESIDENT 1 5000 5000 5000 5000 MANAGER 3 2758.3 2975 2450 8275 ANALYST 2 3000 3000 3000 6000 6行が選択されました。
-GROUP BYは集計関数無しでも使える(DISTINCTと似た感じ…)
-下記例はGROUP BYのグループ化のみの役割
SQL> SELECT deptno 2 FROM emp 3 GROUP BY deptno; DEPTNO ---------- 30 20 10
■DISTINCTとGROUP BY
-DISTINCTは主にUNIQUE(重複解消)なコラム、レ-コードを検索する場合使用する。
-GROUP BYはデータをグループ化して結果を検索する時に使用する。
-DISTINCTでGROUP BYも処理できるクエリ―もある。
-2つともOracle9iまではsortを利用しデータを作ったが、Oracle10gからはHashを利用して処理している。
--DISTINCTでのUNIQUE化処理 SQL> SELECT DISTINCT deptno FROM emp; DEPTNO ---------- 30 20 10 --GROUP BYでのUNIQUE化処理 SQL> SELECT deptno FROM emp GROUP BY deptno; DEPTNO ---------- 30 20 10 --結果は同じ!
しかし、GROUP BYとDISTINCTは各自特有の機能がある
集計関数を使用して特定グループに区分する時はGROUP BY、特定グループに区分しないで重複したデータを除去する場合はDISTINCTを使用するのが望ましい。
--下記の例はDISTINCTを使用するのが効率的 SQL> SELECT COUNT(DISTINCT d.deptno) "重複除去数", 2 COUNT(d.deptno) "全体数" 3 FROM emp e, dept d 4 WHERE e.deptno = d.deptno; 重複除去数 全体数 ---------- ---------- 3 13 --集計関数が必要な場合はGROUP BYを使用する SQL> SELECT deptno, MIN(sal) 2 FROM emp 3 GROUP BY deptno; DEPTNO MIN(SAL) ---------- ---------- 30 950 20 800 10 1300
■HAVING
-WHEREでは集計関数を使用出来ない
-HAVINGは集計関数を持って条件比較をする時に使用する
-HAVINGはGROUP BYと一緒に使用される
下記例は社員数が3名を超える部署と社員数を検索する例
SQL> SELECT b.dname, COUNt(a.empno) "社員数" 2 FROM emp a, dept b 3 WHERE a.deptno = b.deptno 4 GROUP BY dname 5 HAVING COUNT(a.empno) > 3; DNAME 社員数 -------------- ---------- RESEARCH 5 SALES 5
下記例は給与合計が5000を超えるJOBに関してJOBと給与の合計を検索する例、
但しSALESは除外して給与合計の降順で整列した。
SQL> SELECT job, SUM(sal) "給与合計" 2 FROM emp 3 WHERE job != 'SALES' --SALESは除外 4 GROUP BY job --業務別にGROUP BY 5 HAVING SUM(sal) > 5000 --給与合計が5000を超える条件 6 ORDER BY SUM(sal) DESC; --給与合計の降順で整列 JOB 給与合計 --------- ---------- MANAGER 8275 ANALYST 6000
■GROUPING SETS
-GROUPING SETS関数はGROUP BYの拡張した形でGROUP BYに複数のグループ化条件を設定できる。
-GROUPING SETS関数の結果は各GROUP条件を実施した結果をUNION ALLした結果と同じ
-GROUPING SETS関数でUNION ALL等を使用して複雑に作成されたSQL文をシンプルにまとめられる。
下記はGROUPING SETS関数とGROUP BY, UNION ALLを使用して同じ結果を出力する例
--GROUPING SETS使用 SQL> SELECT deptno, job, SUM(sal) 2 FROM emp 3 GROUP BY GROUPING SETS(deptno, job); DEPTNO JOB SUM(SAL) ---------- --------- ---------- 30 8150 20 10875 10 8750 CLERK 4150 SALESMAN 4350 PRESIDENT 5000 MANAGER 8275 ANALYST 6000 --GROUP BYとUNION ALL使用 SQL> SELECT NULL deptno, job, SUM(sal) 2 FROM emp 3 GROUP BY job 4 UNION ALL 5 SELECT deptno, NULL job ,SUM(sal) 6 FROM emp 7 GROUP BY deptno; DEPTNO JOB SUM(SAL) ---------- --------- ---------- CLERK 4150 SALESMAN 4350 PRESIDENT 5000 MANAGER 8275 ANALYST 6000 30 8150 20 10875 10 8750
0 件のコメント:
コメントを投稿