【SQLの基礎知識⑬】 出力結果をグループごとに集計する(GROUP BY・HAVING)

SQLの基礎知識
この記事は約5分で読めます。

SQLでは単純な集計だけではなく、列の値でグループを作って集計することもできます。この時に使うのがGROUP BY句です。

スポンサーリンク

グループに分けて集計する GROUP BY句

GROUP BY句は、指定された列の値が同じ行をひとまとめにすることで、表内のデータをいくつかのグループに分けます。そして、分割されたグループそれぞれに対して集計を行うことができます。

ここでは、次の「売上」表を使って解説を進めます。なお、集計関数に関しては、こちらの集計関数のリファレンスを参照してください。

SQLリファレンス > 関数
ORACLE、MS-SQL Server、MS-Access、MySQLで使用する関数の一覧表です。いちれべ.comは、オラクル、MS-SQL Server、MS-Access で使用可能か一目でわかるのが特徴のSEサポートサイトです。

表:売上

商品名カテゴリ単価販売数量
割れない卵非実用商品30012
温まらない水非効率商品98015
結べない紐非効率商品1506
開けない本非実用商品45010
沈む板奇想天外商品10004
硬いプリンびっくり食品12018
書式 GROUP BY <列名>

このように記述すると列名に指定された列の値を、同じ値ごとにグループ化します。SELECT文として記述すると次のようになります。

書式 SELECT <列名1> , <集計関数> (<列名2>) ・・・
FROM <表名> GROUP BY <列名1> ;
実際にGROUP BY句を用いたSQL文を作成してみましょう。次のSQL文では、GROUP BY句に「カテゴリ」列を指定し、数を数えるCOUNT関数と、値を合計するSUM関数を使用しています。これにより、グループ分けした各カテゴリごとの商品点数の集計と、各カテゴリの販売個数の合計を求めています。
SQL文
SELECT カテゴリ,COUNT(*) 商品点数,SUM(販売数量) 販売個数 FROM 売上 ORDER BY カテゴリ;
実行結果

カテゴリ商品点数販売個数
非実用商品222
非効率商品221
奇想天外商品14
びっくり食品118
ところで、GROUP BY句の記述では気を付けなくてはならないことがあります。それは、SELECTキーワードの後ろに指定されている列名の記述です。GROUP BY句を用いたときには、GROUP BY句で指定された列名以外の列名をそのまま記述するとSQL文がエラーになるということです。次のような式はエラーが発生します。
SQL文
SELECT カテゴリ,販売数量 FROM 売上 GROUP BY カテゴリ;
実行結果
エラーが発生しました。
この例では、GROUP BY句に「カテゴリ」列は指定されていますが、「販売数量」列が指定されていないのでエラーになっています。
このエラーを回避するためには、GROUP BY句に指定してある列名以外をSELECT句に記述する場合には、指定した列の値が1つに決まるように記述する必要があります。列の値を1つにするには、ここまで使ったように、主に集計関数を使います。

グループ化されたデータに条件を設定するHAVING句

GROUP BY句は、指定した列の値に従ってデータをまとめる機能を持ちます。しかし、このひとまとまりになったデータ、またはそれらの集計をさらに条件によって絞り込みたい場合があります。このようなときに用いるのがHAVING句です。

書式 GROUP BY <列名> HAVING <検索条件>

HAVING句の後ろには条件式と論理演算子を用いて、検索条件を記述することができます。HAVING句は、GROUP BY句に指定された列の値によりう、グループ化されたデータに対して条件判断をするのです。

SQL文
SELECT カテゴリ, AVG(単価) 平均単価, SUM(販売数量) 販売数量
FROM 売上 GROUP BY カテゴリ HAVING AVG(単価) > 500;
実行結果

カテゴリ平均単価販売数量
非効率商品56521
奇想天外商品10004
AVG関数は、値の平均を計算する関数です。ここでHAVING句に指定した条件は「カテゴリ」列でグループ化したデータの単価の平均が「500より大きい」データを求めています。そのため。結果の「平均単価」列の値が500より大きいものだけが読み出されます。
HAVING句には、論理演算子を用いることもできます。そのため、次のような問合せも可能です。
SQL文
SELECT カテゴリ, AVG(単価) 平均単価, SUM(販売数量) 販売数量
FROM 売上 GROUP BY カテゴリ HAVING AVG(単価) > 500 AND COUNT(*) >= 2;
実行結果

カテゴリ平均単価販売数量
非効率商品56521

HAVING句に2つの条件式が指定され、両方を満たすものだけが結果として返されます。平均単価が500以上で、しかもカテゴリに分けたグループの中に、商品が2つ以上あるカテゴリだけが結果として返されています。

ところで、ここで不思議に思われた方はいませんか?そうです、WHERE句をなぜ使わないかということです。それは、WHERE句の条件判断がGROUP BY句が実装されるよりも前に行われるからです。そのためGROUP BY句によってまとめられたデータの集計結果を評価することができないのです。

さらにHAVING句の必要性を挙げるならば、WHERE句での条件は行に対して判断を行うため、WHERE句には集計関数を記述することができません。そのために、どのように記述したとしても、WHERE句ではグループ化したデータに対して絞り込みができないことになります。

このような理由があり、GROUP BY句でグループ化したデータに対して絞り込みを行いたい場合には、HAVING句を使うことになります。

関連リンク

次の章へ進む
【SQLの基礎知識⑭】 表の指定(FROM句)と結合
SQLにおける表の指定と結合について解説します。具体的なSQL文を使って、まずはFROM句の記述について解説し、そのあとで複数の表の結合について解説します。いちれべ.comは、オラクル、MS-SQL、MS-Access で使用可能か一目でわかるサイトです。
目次
【SQLの基礎知識】基本ルールや基礎の基礎をマスターしよう
こちらの記事を読み進めることで、SQLの基礎が充分に身に付きます。これからSQLを身に着けたい初心者・入門者の方に最適です。データベース製品ごとに表現方法が異なることがありますので、ある程度SQLのスキルがある方も利用できるサイトです。

タイトルとURLをコピーしました