SQLでは単純な集計だけではなく、列の値でグループを作って集計することもできます。この時に使うのがGROUP BY句です。
グループに分けて集計する GROUP BY句
GROUP BY句は、指定された列の値が同じ行をひとまとめにすることで、表内のデータをいくつかのグループに分けます。そして、分割されたグループそれぞれに対して集計を行うことができます。
ここでは、次の「売上」表を使って解説を進めます。なお、集計関数に関しては、こちらの集計関数のリファレンスを参照してください。
表:売上
商品名 | カテゴリ | 単価 | 販売数量 |
割れない卵 | 非実用商品 | 300 | 12 |
温まらない水 | 非効率商品 | 980 | 15 |
結べない紐 | 非効率商品 | 150 | 6 |
開けない本 | 非実用商品 | 450 | 10 |
沈む板 | 奇想天外商品 | 1000 | 4 |
硬いプリン | びっくり食品 | 120 | 18 |
このように記述すると列名に指定された列の値を、同じ値ごとにグループ化します。SELECT文として記述すると次のようになります。
FROM <表名> GROUP BY <列名1> ;
SELECT カテゴリ,COUNT(*) 商品点数,SUM(販売数量) 販売個数 FROM 売上 ORDER BY カテゴリ;
カテゴリ | 商品点数 | 販売個数 |
非実用商品 | 2 | 22 |
非効率商品 | 2 | 21 |
奇想天外商品 | 1 | 4 |
びっくり食品 | 1 | 18 |
SELECT カテゴリ,販売数量 FROM 売上 GROUP BY カテゴリ;
エラーが発生しました。
グループ化されたデータに条件を設定するHAVING句
GROUP BY句は、指定した列の値に従ってデータをまとめる機能を持ちます。しかし、このひとまとまりになったデータ、またはそれらの集計をさらに条件によって絞り込みたい場合があります。このようなときに用いるのがHAVING句です。
HAVING句の後ろには条件式と論理演算子を用いて、検索条件を記述することができます。HAVING句は、GROUP BY句に指定された列の値によりう、グループ化されたデータに対して条件判断をするのです。
SELECT カテゴリ, AVG(単価) 平均単価, SUM(販売数量) 販売数量
FROM 売上 GROUP BY カテゴリ HAVING AVG(単価) > 500;
カテゴリ | 平均単価 | 販売数量 |
非効率商品 | 565 | 21 |
奇想天外商品 | 1000 | 4 |
SELECT カテゴリ, AVG(単価) 平均単価, SUM(販売数量) 販売数量
FROM 売上 GROUP BY カテゴリ HAVING AVG(単価) > 500 AND COUNT(*) >= 2;
カテゴリ | 平均単価 | 販売数量 |
非効率商品 | 565 | 21 |
HAVING句に2つの条件式が指定され、両方を満たすものだけが結果として返されます。平均単価が500以上で、しかもカテゴリに分けたグループの中に、商品が2つ以上あるカテゴリだけが結果として返されています。
ところで、ここで不思議に思われた方はいませんか?そうです、WHERE句をなぜ使わないかということです。それは、WHERE句の条件判断がGROUP BY句が実装されるよりも前に行われるからです。そのためGROUP BY句によってまとめられたデータの集計結果を評価することができないのです。
さらにHAVING句の必要性を挙げるならば、WHERE句での条件は行に対して判断を行うため、WHERE句には集計関数を記述することができません。そのために、どのように記述したとしても、WHERE句ではグループ化したデータに対して絞り込みができないことになります。
このような理由があり、GROUP BY句でグループ化したデータに対して絞り込みを行いたい場合には、HAVING句を使うことになります。