グループ化したデータを取得する条件を設定する(HAVING句)

広告
eyecatch

HAVING 句を指定すると GROUP BY 句によってグループ化されて取得したデータに関して、取得する条件を設定することができます。ここでは HAVING 句を使ってグループ化したデータを取得する条件を設定する方法と、 WHERE 句と合わせて利用する場合の注意点などについて解説します。

※ GROUP BY 句の使い方については「データをグループ化する(GROUP BY句)」を参照されてください。

グループ化したデータを取得する条件を設定する

HAVING 句は GROUP BY 句によってグループ化が行われたデータに対して条件を指定してデータを絞り込む場合に使用します。使い方は次の通りです。

SELECT col_name1 [, col_name2 ...] FROM table_name
  GROUP BY col_name, ... HAVING where_condition

HAVING 句が記述されている場合、グループ化したデータを 1 件取得しようとするたびに条件式( where_condition )を評価して、結果が TRUE となった場合にデータを取得します。HAVING 句の条件式に記述できるのはグループ化に指定したカラム名や、関数などを使ってグループ単位で集計した結果だけです。

使い方は次のとおりです。

[例] グループ毎に price カラムの値平均を計算し、平均の値が 100 を超えるデータを取得
SELECT AVG(price) FROM goodslist GROUP BY category HAVING AVG(price) > 100;

※ AVG 関数はカラムに格納されている値の平均値を取得する関数です。詳細は「AVG関数 (指定のカラムに格納されている値の平均値を取得する)」を参照されてください。

-- --

それでは実際に試してみます。次のようなテーブルを作成しました。

create table report (branch varchar(10), name varchar(10), sales int);

グループ化したデータを取得する条件を設定する(1)

テーブルには次のようなデータを追加してあります。

insert into report values ('Tokyo', 'Yamada', 150);
insert into report values ('Osaka', 'Nishi', 280);
insert into report values ('Sapporo', 'Suzuki', 190);
insert into report values ('Nagoya', 'Honda', 240);
insert into report values ('Osaka', 'Tani', 120);
insert into report values ('Nagoya', 'Endou', 130);
insert into report values ('Tokyo', 'Kuroda', 300);
insert into report values ('Sapporo', 'Yoshida', 150);

グループ化したデータを取得する条件を設定する(2)

それでは branch カラムの値を基準としてグループ化を行い、グループ毎に sales カラムの値の平均値を取得します。

select branch, avg(sales) from report group by branch;

グループ化したデータを取得する条件を設定する(3)

HAVING 句を使って sales カラムの平均値が 200 以上のデータだけを取得するように変更してみます。

select branch, avg(sales) from report group by branch having avg(sales) >= 200;

グループ化したデータを取得する条件を設定する(4)

このように HAVING 句を使うことで、グループ化して取得したデータに対して条件式を設定することができます。

別名を割り当てて条件式の中で使う

AS 句を使用することでカラムに別名を割り当てることができますが、割り当てた別名を HAVING 句の条件式の中で使用することができます。( AS 句については「カラムに別名を付ける(AS句)」を参照されてください)。

先ほど作成したテーブルに対して branch カラムの値を基準としてグループ化を行い、グループ毎に sales カラムの値の平均値を取得しましたが、平均値に対して別名を割り当てるには次のように実行します。

select branch, avg(sales) as average from report group by branch;

別名を割り当てて条件式の中で使う(1)

割り当てた別名は HAVING 句の条件式の中で使用することができます。

select branch, avg(sales) as average from report group by branch having average >= 200;

別名を割り当てて条件式の中で使う(2)

WHERE 句と HAVING 句を同時に記述した場合

WHERE 句と HAVING 句を同時に記述した場合、まず WHERE 句で設定した条件を満たすデータだけを対象にグループ化が行われます。そしてグループ化したデータに対して HAVING 句で設定した条件を満たすデータだけを取得することになります。

それでは先ほど作成したテーブルに対して、 sales カラムの値が 150 以上のデータだけを対象にグループ化を行い、グループ毎に sale カラムの平均を取得し、その平均が 200 以上のものだけを取得してみます。

select branch, avg(sales) as average from report where sales >= 150 group by branch having average >= 200;

WHERE 句と HAVING 句を同時に記述した場合(1)

なお WHERE 句や GROUP BY 句をまとめて記述する順番は次の通りです。

SELECT col_name FROM table_name
    [WHERE where_condition]
    [GROUP BY col_name, ... [WITH ROLLUP]]
    [HAVING where_condition]

-- --

HAVING 句を使ってグループ化したデータを取得する条件を設定する方法について解説しました。

MySQLの使い方の他の記事を見てみる

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)
Profile
profile_img

著者 / TATSUO IKURA

初心者~中級者の方を対象としたプログラミング方法や開発環境の構築の解説を行うサイトの運営を行っています。