支援対象地域:札幌、仙台、関東、愛知、関西、広島、福岡


SQLのHAVING句

OracleやMySQLはRDB(リレーショナルデータベース)と呼ばれるデータベースです。

OracleやMySQLなどのデータベースを操作するためにはSQLを使用します。SQLの中にHAVING句というものがあります。

ここではOracleなどのデータベースで使用されるHAVING句について説明します。

Having句とは?

Having句とは抽出条件を指定するものです。

基本構文

SELECT [表示したい内容] FROM [テーブル名] HAVING [抽出条件];

FROM [テーブル名]のあとにHAVING句を記述します。

サンプルコード

+-------+--------+-----+--------+
| ID    | NAME   | AGE | DEPTNO |
+-------+--------+-----+--------+
| NO.1  | 山田   |  20 |      1 |
| NO.2  | 田中   |  20 |      3 |
| NO.3  | 山内   |  31 |      2 |
| NO.4  | 山中   |  35 |      1 |
| NO.5  | 花田   |  40 |      1 |
| NO.6  | 川田   |  45 |      2 |
| NO.7  | 上杉   |  50 |      1 |
| NO.8  | 伊達   |  50 |      1 |
| NO.9  | 川原   |  55 |      3 |
| NO.10 | 小田   |  26 |      3 |
| NO.11 | 豊臣   |  36 |      1 |
| NO.12 | 中田   |  26 |      4 |
| NO.13 | 小川   |  36 |      4 |
+-------+--------+-----+--------+

これはsampletbというテーブル(表名)です。

ここからDEPTNOが1であるものを取り出すには以下のコードを使用します。

SELECT * FROM sampletb HAVING DEPTNO="1";

+-------+--------+-----+--------+
| ID    | NAME   | AGE | DEPTNO |
+-------+--------+-----+--------+
| NO.1  | 山田   |  20 |      1 |
| NO.4  | 山中   |  35 |      1 |
| NO.5  | 花田   |  40 |      1 |
| NO.7  | 上杉   |  50 |      1 |
| NO.8  | 伊達   |  50 |      1 |
| NO.11 | 豊臣   |  36 |      1 |
+-------+--------+-----+--------+

このようにDEPTNOが1のものが抽出されています。

このサンプルコードではMySQLを使用していますが、Oracleなどのデータベースでも使用できます。

WHERE句とは?

HAVING句と似たようなものでWHERE句があります。

先ほど使用したsampletbからWHERE句を使用してDEPTNOが1であるものを取り出すには以下のコードを使用します。

SELECT * FROM sampletb WHERE DEPTNO="1";
+-------+--------+-----+--------+
| ID    | NAME   | AGE | DEPTNO |
+-------+--------+-----+--------+
| NO.1  | 山田   |  20 |      1 |
| NO.4  | 山中   |  35 |      1 |
| NO.5  | 花田   |  40 |      1 |
| NO.7  | 上杉   |  50 |      1 |
| NO.8  | 伊達   |  50 |      1 |
| NO.11 | 豊臣   |  36 |      1 |
+-------+--------+-----+--------+

HAVING句と同じ結果がでています。

同じ結果がでていますが、WHERE句とHAVING句には違いがあります。

こちらのコードもMySQLを使用していますがOracleなどのデータベースでも使用できます。

WHERE句とHAVING句の違い

SQLは以下の順序で実行されます。

FROM

JOIN

WHERE

GROUP BY

SUM AVG

HAVING

SELECT

ORDER

LIMIT

つまりGROUP BYでグループ化する前に抽出するのがWHERE句で、グループ化した後に抽出するのがHAVING句となります。

HAVING句を使用する際の注意点

+-------+--------+-----+--------+
| ID    | NAME   | AGE | DEPTNO |
+-------+--------+-----+--------+
| NO.1  | 山田   |  20 |      1 |
| NO.2  | 田中   |  20 |      3 |
| NO.3  | 山内   |  31 |      2 |
| NO.4  | 山中   |  35 |      1 |
| NO.5  | 花田   |  40 |      1 |
| NO.6  | 川田   |  45 |      2 |
| NO.7  | 上杉   |  50 |      1 |
| NO.8  | 伊達   |  50 |      1 |
| NO.9  | 川原   |  55 |      3 |
| NO.10 | 小田   |  26 |      3 |
| NO.11 | 豊臣   |  36 |      1 |
| NO.12 | 中田   |  26 |      4 |
| NO.13 | 小川   |  36 |      4 |
+-------+--------+-----+--------+

このテーブルはsampletbという名前です。

このテーブルからDEPTNOをグループ化し、AGEが30以上で取り出された件数が2以上の件数をDEPTNO順に表示するには以下のコードを使用します。

 SELECT DEPTNO,COUNT(*)
    -> FROM sampletb
    -> WHERE AGE >=30
    -> GROUP BY DEPTNO
    -> HAVING COUNT(*) >=2
    -> ORDER BY DEPTNO;
+--------+----------+
| DEPTNO | COUNT(*) |
+--------+----------+
|      1 |        5 |
|      2 |        2 |
+--------+----------+

このように条件に合ったものが抽出され表示されています。

こちらのコードもMySQLを使用していますがOracleなどのデータベースでも使用できます。

ですがHAVING句には注意点があります。

HAVING句は必ずWHERE句の後ろ、かつORDER BY句の前に記述する必要があります。

 SELECT DEPTNO,COUNT(*)
    -> FROM sampletb
    -> HAVING COUNT(*) >=2
    -> GROUP BY DEPTNO
    -> WHERE AGE >=30
    -> ORDER BY DEPTNO;

このように記述を行うとエラーが発生するため注意が必要です。

これはMySQLだけでなくOracleなどのデータベースでも注意が必要です。

まとめ

OracleやMySQLなどのデータベースで使用できるHAVING句について説明しました。HAVING句は抽出条件を指定するもので、WHERE句と似たものとなっています。

主に、HAVING句はGROUP BYでグループ化した後に条件をつけて抽出したい時に使用します。ですが記述する順番に注意が必要です。

この記事ではMySQLを使用してサンプルコードを紹介していますがOracleなどのデータベースでも使用可能です。ですが、OracleやMySQLなど様々なデータベースがあり、データベースによって使用できるコマンドがあったりしますので注意が必要です。