グループ化したデータを取得する条件を設定する(HAVING句)
HAVING 句を指定すると GROUP BY 句によってグループ化されて取得したデータに関して、取得する条件を設定することができます。ここでは MySQL で HAVING 句を使ってグループ化したデータを取得する条件を設定する方法と、 WHERE 句と合わせて利用する場合の注意点などについて解説します。
※ GROUP BY 句の使い方については「データをグループ化する(GROUP BY句)」を参照されてください。
(Last modified: )
グループ化したデータを取得する条件を設定する
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);
テーブルには次のようなデータを追加してあります。
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);
それでは branch カラムの値を基準としてグループ化を行い、グループ毎に sales カラムの値の平均値を取得します。
select branch, avg(sales) from report group by branch;
HAVING 句を使って sales カラムの平均値が 200 以上のデータだけを取得するように変更してみます。
select branch, avg(sales) from report group by branch having avg(sales) >= 200;
このように HAVING 句を使うことで、グループ化して取得したデータに対して条件式を設定することができます。
別名を割り当てて条件式の中で使う
AS 句を使用することでカラムに別名を割り当てることができますが、割り当てた別名を HAVING 句の条件式の中で使用することができます。( AS 句については「カラムに別名を付ける(AS句)」を参照されてください)。
先ほど作成したテーブルに対して branch カラムの値を基準としてグループ化を行い、グループ毎に sales カラムの値の平均値を取得しましたが、平均値に対して別名を割り当てるには次のように実行します。
select branch, avg(sales) as average from report group by branch;
割り当てた別名は HAVING 句の条件式の中で使用することができます。
select branch, avg(sales) as average from report group by branch having average >= 200;
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 句や GROUP BY 句をまとめて記述する順番は次の通りです。
SELECT col_name FROM table_name [WHERE where_condition] [GROUP BY col_name, ... [WITH ROLLUP]] [HAVING where_condition]
-- --
HAVING 句を使ってグループ化したデータを取得する条件を設定する方法について解説しました。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。