GROUP BY句は非常に有益ではありますが、1つ注意しなければならない点があります。GROUP BY句を利用する場合、SELECT句ではGROUP BY句で指定した列と集計関数のみを利用できます。具体的には次のようなクエリを発行した場合、エラーとなります。
SELECT Name,Count(*) 商品数 FROM PRODUCTION.PRODUCT GROUP BY Color 結果 メッセージ 8120、レベル 16、状態 1、行 1 列 'PRODUCTION.PRODUCT.Name' は選択リスト内では無効です。この列は集計関数または GROUP BY 句に含まれていません。
このサンプルでは、「Color」列でグループ化を行った結果から「Name」列の出力と集計関数の実行を行おうとしています。しかし、「Name」列の値は行ごとに異なりますが、「Color」列をグループ化した結果に複数の「Name」列の値を表示することはできません。このためエラーとなります。
「Name」列をGROUP BY句に加えるとエラーは発生しませんが、「Name」と「Color」の値が同じ行をグループ化、という動作になってしまいます。「Name」列の値は行ごとに異なるため、グループ化をまったく行えません。
SELECT Name,Count(*) 商品数 FROM PRODUCTION.PRODUCT GROUP BY Name,Color 結果 Name 商品数 -------------------------------------------------- ----------- Adjustable Race 1 All-Purpose Bike Stand 1 AWC Logo Cap 1 …以下略…
このように、SELECT句で指定する列は、GROUP BY句で指定された列のみを利用することができます。ただし、集計関数内で指定する列はGROUP BY句に含まれている必要はありません。次の例では、月ごとの平均受注額を算出しています。
SELECT MONTH(OrderDate) as 月,AVG(TotalDue) 平均受注額 FROM Sales.SalesOrderHeader GROUP BY MONTH(OrderDate) ORDER BY 月 結果 月 平均受注額 ----------- --------------------- 1 3032.771 2 4483.8574 3 3828.1778 4 3529.4124 5 4669.3217 6 4070.0469 7 4628.4326 8 6144.7454 9 5691.2663 10 3850.3666 11 5690.703 12 4388.1861
集計関数を利用した結果は常に1つの値にまとめられるため、GROUP BY句に含まれない列を指定することができるのです。
以上のように、GROUP BY句と集計関数を組み合わせることにより、多様な集計を行うことができます。データベースに対しデータを蓄積する目的の1つとして、集計・分析を行う、というものがありますが、GROUP BY句と集計関数の組み合わせによってこれらの目的を達成することが可能です。
今回はORDER BY句とGROUP BY句を取り上げました。どちらもSQLを利用するうえで、たびたび利用することになります。特にGROUP BY句は動作がこれまでのSQLとは大きく異なるため、その利用法や応用にしっかり慣れておきましょう。
次回は、グループ化した結果に対して抽出条件を指定できる「HAVING」句を取り上げる予定です。お楽しみに!(次回へ続く)
石橋潤一
株式会社システムインテグレータ勤務。Web+DBの業務アプリをメインに開発に携わる。@IT連載記事「SQL Server 2005を使いこなそう」「SQL Server 2005 CTPレビュー」執筆のほか、著書に『DBマガジン別冊 SQL Server 2005徹底活用ガイド』(翔泳社刊/共著)、『ASP.NET+SQL Server ゼロからはじめるWebアプリケーション』(ソフトバンクパブリッシング刊/共著)。
Copyright © ITmedia, Inc. All Rights Reserved.