SQL ServerのT-SQLクエリ言語には、多くのデータ取得オプションがあります。それには、SQLデータベースのクエリを実行する能力、合計関数、カウント集約関数、および列をグループ化する機能が含まれます。 SQL GROUP BY句 はこれらすべての機能を利用することができます。この記事では、GROUP BY句が単独で使用される方法、または集約関数の1つと組み合わせてグループ化に基づいた計算を実行する方法を示します。
SQL GROUP BY句はどのように機能しますか?
SQL GROUP BY句は、データを同一のデータのグループに配置するために SELECT文 と共に使用されます。この句は、SELECT文のWHERE句の後に続きます。
この句は、通常、SUM、COUNT、AVG、MAX、またはMINなどの集約関数と一緒に使用され、グループ化されたデータで計算を実行できます。製品ID、日付、または説明などのさまざまな列タイプでデータをグループ化できます。
基本的なGROUP BY構文は非常にシンプルです。
SELECT column1, aggregate_function(column2) FROM table_name GROUP BY column1;
ここでは、基本的なSELECT文と一緒に使用されるGROUP BY句を見ることができます。SELECT文は2つの列を取得し、2番目の列では集計関数が使用されています。
集計関数の使用は技術的に必須ではありませんが、GROUP BY句の非常に一般的な補足です。グループ化は最初の列に含まれるデータを対象とします。
さらに詳しく見て、GROUP BY句の動作を確認しましょう。
SELECT文でSQL GROUP BYを使用する
まず、集計関数を追加せずに単純なSELECT文とともにSQL GROUP BY句を使用する方法を見てみましょう。次のリストは、AdventureWorksLT2019サンプルデータベースのSalesLT.SalesOrderDetailテーブルから ‘Product ID’列を取得してグループ化します。
USE AdventureWorksLT2019; SELECT ProductID FROM SalesLT.SalesOrderDetail GROUP BY ProductID;
これにより、注文されたすべてのProductIDのリストが返されます。次の図で確認できます。

集計関数を使用したSQL GROUP BYの使用
SQLのGROUP BY句は、カウント、合計、平均、またはグループ化されたすべての列の要約を提供することができる集計関数のいずれかと共によく使用されます。次のステートメントは、AdventureWorksLT2019データベースのSalesLT.Productテーブルから各商品カテゴリにおける商品の総数を見つけるためにGROUP BYを使用しています。
USE AdventureWorksLT2019; SELECT ProductCategoryID, COUNT(*) AS TotalProducts FROM SalesLT.Product GROUP BY ProductCategoryID;
この例では、SELECTステートメントはSalesLT.Productテーブルの’ProductCategoryID’列を返し、COUNT(*)集計関数を使用して各カテゴリの商品数をカウントします。ここで、GROUP BY句は’ProductCategoryID’で結果をグループ化しますが、SELECT COUNT関数は各商品カテゴリの商品の総数を計算します。COUNT(*)関数の結果は’TotalProducts’という別名を使用します。
このクエリの結果は、次の図に示すように、GROUP BY句を使用して計算された各商品カテゴリの商品の総数を示しています。要約情報はCOUNT(*)集計関数によって返されます。

SQL GROUP BYを複数の列で使用する
SQLのGROUP BY関数は、単一の列で動作するだけでなく、同じクエリで複数の列と同時に使用することもできます。
SalesLT.Productテーブルから、AdventureWorksLT2019データベース内の2つの列を使用してGROUP BY句を使用する例を見てみましょう。次のクエリは、各製品カテゴリと製品モデルごとの製品の合計数を取得する方法を示しています。
USE AdventureWorksLT2019; SELECT ProductCategoryID, ProductModelID, COUNT(*) AS TotalProducts FROM SalesLT.Product GROUP BY ProductCategoryID, ProductModelID;
ここでは、「ProductCategoryID」と「ProductModelID」の列を両方取得し、COUNT(*)集計関数を使用して各製品カテゴリとサブカテゴリの製品数をカウントしています。この例では、GROUP BY句が「ProductCategoryID」と「ProductModelID」の両方の結果をグループ化しています。これにより、2つの異なる列に基づいて2つの異なるグループが作成されます。
このクエリの結果は、次の図に示されています。これらの結果は、製品および製品モデルの合計数を示し、合計数は列エイリアスのTotalProductsを使用して取得されます。

HAVING句を使用したSQLのGROUP BY
GROUP BY句をHAVING句と組み合わせる一般的な使用法の1つは、HAVING句を使用してクエリの結果をデータのグループ化に適用する条件に基づいてフィルタリングすることです。条件は通常のデータ型の列または集計関数に適用できます。
SQLのGROUP BY句とHAVING句を使った例として、AdventureWorksLT2019データベースを使用します。この例では、SalesLT.SalesOrderHeaderテーブルで合計注文金額が$2000を超える顧客を示します。ここでは、GROUP BY句を使用して注文を顧客ごとにグループ化し、その後、HAVING句で合計注文金額に基づいて顧客をフィルタリングします。
USE AdventureWorksLT2019; SELECT c.CustomerID, c.FirstName, c.LastName, SUM(soh.TotalDue) AS TotalOrderAmount FROM SalesLT.Customer c JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID GROUP BY c.CustomerID, c.FirstName, c.LastName HAVING SUM(soh.TotalDue) > 2000;
- このコードリストでは、SalesLT.Customerテーブルが’SalesLT.SalesOrderHeader’テーブルと’CustomerID’列で結合されています。
- SELECTリストは、’CustomerID’、’FirstName’、’LastName’、および’TotalOrderAmount’を取得しています。
- GROUP BY句は結果を顧客ごとにグループ化するために使用されます。
- SUM()集計関数は、各顧客の合計注文金額を計算します。
- HAVING句は、グループ化された結果をフィルタリングし、合計注文金額が$2000を超える顧客のみを選択します。
このコードリストの結果は、次の図で確認できます:

ORDER BY句とともにSQLのGROUP BYを使用する
ORDER BY句と組み合わせて、1つまたは複数の列で結果セットをソートすることもできます。次の例では、AdventureWorksLT2019データベースを使用しています。GROUP BY句とORDER BY句を使用した例を示すために、前の例のコードにORDER BY句を追加して、結果をソートして最大の注文金額を降順で表示します。
USE AdventureWorksLT2019; SELECT c.CustomerID, c.FirstName, c.LastName, SUM(soh.TotalDue) AS TotalOrderAmount FROM SalesLT.Customer c JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID GROUP BY c.CustomerID, c.FirstName, c.LastName HAVING SUM(soh.TotalDue) > 2000 ORDER BY TotalOrderAmount DESC;
次の図で結果を確認できます。これらの結果は、降順で$2000を超える注文がある顧客のリストを表示し、最大の注文を持つ顧客が一番上に表示されます。

SQL GROUP BY句では様々なことができることがわかりました。複数の列とともにGROUP BY句を使用する方法、およびHAVING句とORDER BY句を追加して結果をフィルタリングおよびソートする方法を示しました。
いつも通り、SQL GROUP BY句に関する質問があればお気軽にお尋ねください。SQL Serverについて詳しく学びたい場合は、私のSQL Server Essentialシリーズの過去の記事をチェックしてみてください。
Source:
https://petri.com/sql-group-by/