SQL Server - GROUP BY

提供: MochiuWiki : SUSE, EC, PCB

概要



複数の行を各グループに集約する (GROUP BY)

下表に示すテーブルがある。

T_Salesテーブル
Shop_ID Category Name Price
1 Fruit Apple 300
1 Fruit Orange 200
1 Vegetable Carrot 200
2 Vegetable Eggplant 100


以下に、GROUP BY句のシンタックスを示す。

GROUP BY句で指定したカラム名で、複数の行を集約する。
SELECT句のカラム名とGROUP BY句のカラム名は一致している必要はない。

 SELECT <カラム名> FROM <テーブル名> 
 GROUP BY <カラム名>


以下の例では、上記のT_Salesテーブルに対して、GROUP BY句を使用してデータを抽出している。

 SELECT Category, AVG(Price) 
 FROM T_Sales
 GROUP BY Category;


結果は、以下の通りである。

GROUP BY句で指定したCategoryカラムの値で集約されたレコードが表示される。
また、各レコードごとに集約関数の値が表示される。

Category     AVG(Price)
Fruit        250
Vegetable    150


以下の例では、GROUP BY句にShop_IDカラムとCategoryカラムを追加する時、Shop_IDカラムとCategoryカラムでレコードが集約されている。

 SELECT Shop_ID, Category, AVG(Price)
 FROM T_Sales
 GROUP BY Shop_ID, Category
 ORDER BY Shop_ID, Category;


Shop_ID     Category     AVG(Price)
1           Fruit        250
1           Vegetable    200
2           Vegetable    100



集約関数の値に条件を指定する (HAVING句)

HAVING句の使用

下表に示すテーブルがある。

T_Salesテーブル
Shop_ID Category Name Price
1 Fruit Apple 300
1 Fruit Orange 200
1 Vegetable Carrot 200
2 Vegetable Eggplant 100


以下に、HAVING句のシンタックスを示す。

HAVING句を使用すると、複数のレコードを各グループに集約して、集約関数の値に条件を指定できる。

 SELECT <カラム名>
 FROM <テーブル名>
 GROUP BY <カラム名>
 HAVING <条件>


以下の例では、上記のT_Salesテーブルに対して、HAVING句を使用してデータを抽出している。

 SELECT Category, AVG(Price) 
 FROM T_sales
 GROUP BY Category 
 HAVING AVG(Price) > 200;


以下に、上記のSQL文の処理のイメージを示す。
1. まず、GROUP BY句で指定したCategoryカラムの単位で集約する。

Category AVG(Price)
Fruit 250
Vegetable 150


2. 次に、AVG(Price)のカラムに対して、HAVING句で指定した条件(200より大きい)を満たすレコードが表示される。

Category AVG(Price)
Fruit 250


WHERE句が使用できない場合

以下のように、WHERE句で、集約関数(AVG)の結果を条件にすることはできない。

MySQLでは、以下のメッセージが表示される。

#1111 - 集計関数の使用方法が不正です。


集約関数の結果を条件にする場合は、HAVING句を使用する。

 SELECT Category, AVG(Price) 
 FROM T_Sales 
 WHERE AVG(Price) > 200
 GROUP BY Category;


WHERE句が使用できるパターン

ただし、集約関数の結果以外を条件にする場合は、GROUP BY句とWHERE句が使用できる。

この場合、レコード件数を絞るWHERE句を使用した方がよい。
HAVING句では処理が遅くなる可能性がある。

 SELECT Category, AVG(Price) 
 FROM T_Sales
 WHERE Name = 'Apple'
 GROUP BY Category;