SQL 入門 > SELECT 文の活用 (GROUP BY)

検索結果のグループ化 (GROUP BY と HAVING)

サンプルデータ

利用者マスタ(USER_MASTER2)
利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
00201001小泉 純一29
00191001林 喜朗12
00181002少渕 恵三21
00171003橋本 虎太郎33
00011003鳩山 一代8
00001003影のボス<NULL>

グループ化の適用範囲

グルーピング処理は以下のような例題についての解答になる。

  • 部門別に利用者は何人いるか?
  • 部門別に平均在職期間はどれくらいか?

  • 在職期間の平均が XX になる部門はどこか? など

グループ化とは

グループ化とは、SELECT 文抽出したデータ(※1)を指定したキーワードで分類(※2) する。
その結果セットを 指定したキーワード、または、集計ファンクション を使用して取り出すこと意味する。

(※1) 抽出したデータ= WHERE 句で対象のデータを条件付けること。
(※2) 指定したキーワードで分類= GROUP BY 句 抽出結果のグルーピング。

部門でグループ化

  • サンプルデータを グループ化してみる。

SELECT DEPT_NO FROM USER_MASTER2 GROUP BY DEPT_NO

グループ化のイメージ(作業前)

利用者マスタ(USER_MASTER2)
利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
00201001小泉 純一29
00191001林 喜朗12
00181002少渕 恵三21
00171003橋本 虎太郎33
00011003鳩山 一代8
00001003影のボス<NULL>

グループ化 STEP(1)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
00201001小泉 純一29
0019林 喜朗12
00181002少渕 恵三21
00171003橋本 虎太郎33
0001鳩山 一代8
0000影のボス<NULL>

グループ化 STEP(2)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
-1001--
-1002--
-1003--

注目する点はオレンジ色の部分である。オレンジ色の部分はグループ化によって情報が集約される。 この部分を取り出すには、集計関数を使用しなければならない。

集計関数を使用しなければ以下のエラーが発生する。

SQL> SELECT DEPT_NO,USER_NAME FROM USER_MASTER2 GROUP BY DEPT_NO ;
SELECT DEPT_NO,USER_NAME FROM USER_MASTER2 GROUP BY DEPT_NO
               *
行1でエラーが発生しました。:
ORA-00979: GROUP BYの式ではありません。

グループ化の例題の解答

  • 部門別に利用者は何人いるか?

SELECT DEPT_NO, COUNT(*) FROM USER_MASTER2 GROUP BY DEPT_NO ;

グループ化 STEP(1)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
00201001小泉 純一29
0019林 喜朗12
00181002少渕 恵三21
00171003橋本 虎太郎33
0001鳩山 一代8
0000影のボス<NULL>

グループ化 STEP(2)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
COUNT(*)
-1001--2
-1002--1
-1003--3
  • 部門別に平均在職期間はどれくらいか?

SELECT DEPT_NO, AVG(TERM) FROM USER_MASTER2 GROUP BY DEPT_NO ;

グループ化 STEP(1)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
00201001小泉 純一29
0019林 喜朗12
00181002少渕 恵三21
00171003橋本 虎太郎33
0001鳩山 一代8
0000影のボス(※) <NULL>

グループ化 STEP(2)

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
AVG(TERM)
-1001-(29,12)20.5
-1002-(21)21
-1003-(33,8,NULL)(※) 20.5

(※) 集計関数のほとんどが NULL を無視する。

グループ化した後のさらなる条件付け HAVING

在職期間の平均が XX になる部門はどこか? という例題を解答するには、グループ化した結果にさらになる条件付けが必要である。
これには HAVING という句を使用する。HAVING はグループ化した結果セットへの WHERE 条件である。

  • グループ化のみ

SELECT DEPT_NO, AVG(TERM) FROM USER_MASTER2 GROUP BY DEPT_NO ;

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
AVG(TERM)
-1001-(29,12)20.5
-1002-(21)21
-1003-(33,8,NULL)20.5
  • グループ化と HAVING
    HAVING による 条件付け 在職期間の平均が 20.5 の部門を取得する。

SELECT DEPT_NO FROM USER_MASTER2 GROUP BY DEPT_NO
           HAVING AVG(TERM) = 20.5

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
AVG(TERM)
-1001-(29,12)20.5
-1003-(33,8,NULL)20.5
  • WHERE、GROUP BY と HAVING の使用
    これまでの SQL に WHERE 条件を加える。在職期間が 10 以下のものを対象外とする。

SELECT DEPT_NO FROM USER_MASTER2 WHERE TERM<=10 GROUP BY DEPT_NO
           HAVING AVG(TERM) = 20.5

利用者ID
(USER_ID)
部門
(DEPT_NO)
利用者名
(USER_NAME)
在職期間
(TERM)
AVG(TERM)
-1001-(29,12)20.5
-1003-(33,8,NULL)33

部門 1003 は検索結果に該当しなくなる。




スポンサード リンク

ITエンジニア キャリアアップ・転職・求人情報

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ 会員制(無料)の公式技術サイト
Google