SQL GROUP BY句でデータの集計・集約を行う

「社員マスタ」と「売上明細」というテーブルがあります。売上明細テーブルには、社員の売上情報が格納されています。

社員マスタ
社員コード社員名部署コード年齢
1テスト社員1122
2テスト社員2230
3テスト社員3null20
売上明細
売上NO社員コード売上日売上金額
1120150401200
2120150402300
3220150408100
4220150501150
5320150505550

全社員の売上の合計を表示したい。

SQLは下記のようになります。

SELECT MAX(T1.社員名) AS 社員名
    ,SUM(T2.売上金額) AS 売上金額
FROM 社員マスタ AS T1
    LEFT JOIN 売上明細 AS T2
    ON T1.社員コード = T2.社員コード
GROUP BY T1.社員コード
実行結果
社員名売上金額
テスト社員1500
テスト社員2250
テスト社員3550

わかりやすくするために、GROUP BYSELECT句の集計関数を行わずに実行した場合の結果を下記に示します。

SELECT T1.社員コード
    ,T1.社員名
    ,T2.売上金額
FROM 社員マスタ AS T1
    LEFT JOIN 売上明細 AS T2
    ON T1.社員コード = T2.社員コード
実行結果
社員コード社員名売上金額
1テスト社員1200
1テスト社員1300
2テスト社員2100
2テスト社員2150
3テスト社員3550

売上明細テーブルには1社員につき、複数のデータが存在します。なので、同一社員で複数の明細が出力されてしまいます。

同一社員は1行に集約し、かつ売上金額は集約する行の合計値を表示する必要があります。

下記図のようなイメージです。

実行結果
社員コード社員名売上金額
1テスト社員1200+300
1テスト社員1200
1テスト社員1300
2テスト社員2100+150
2テスト社員2100
2テスト社員2150
3テスト社員3550
3テスト社員3550

行を集約するには、GROUP BY句を使用します。

GROUP BY句で指定したカラムの値が同じ行は、1行に集約されます。

複数のカラムを指定した場合は、すべてのカラムの値が同じ行をそれぞれ1行に集約します。

上記の例ではGROUP BY句で社員コードを指定しているので、同一社員(社員コードの値が同じデータ)が1行に集約されます。

GROUP BY句で指定したカラムは、集約する行の値はすべて同じなので、その値がそのまま出力されます。

GROUP BY句で指定したカラム以外のカラムはどのように集約するのかを、SELECT句で指定する必要があります。

集約方法を指定しないと、下記図のように何を出力するのか定まらないからです。

実行結果
社員コード社員名売上金額
1テスト社員1?テスト社員1200?300
1テスト社員1200
1テスト社員1300
2テスト社員2?テスト社員2100?150
2テスト社員2100
2テスト社員2150
3テスト社員3550
3テスト社員3550

集計方法の指定は集計関数(集約関数)を使用します。

主な集計関数
関数名機能
COUNT集計対象の行数を出力
MAX集計対象のなかで最大のものを出力
MIN集計対象のなかで最小のものを出力
SUM集計対象の合計値を出力
AVG集計対象の平均を出力

例題では、売上金額カラムは売上の合計なのでSUM関数を指定しています。

社員コードが同じなら、社員名も同じになるはずなので、社員名カラムにはMAX関数をしています。(最大値でも最小値でも平均値でも値はすべて同じなのでMIN関数やAVG関数でも可能)

もしくは上記と同じ理由でGROUP BY句に社員名も指定するやり方でもできます。

SELECT MAX(T1.社員名) AS 社員名
    ,SUM(T2.売上金額) AS 売上金額
FROM 社員マスタ AS T1
    LEFT JOIN 売上明細 AS T2
    ON T1.社員コード = T2.社員コード
GROUP BY T1.社員コード

--または

SELECT T1.社員名
    ,SUM(T2.売上金額) AS 売上金額
FROM 社員マスタ AS T1
    LEFT JOIN 売上明細 AS T2
    ON T1.社員コード = T2.社員コード
GROUP BY T1.社員コード, T1.社員名

関連記事

  • SQL WITH句でVIEWを作成し重複するSQL文をまとめる

    WITH句でVIEWを作成し重複するSQL文をまとめる方法を説明します。WITH句を使えば1つの副問い合わせ(SQL)を複数の箇所で使いまわすことができます。


  • SQL WHERE句でデータを絞り込む

    WHERE句でデータを絞り込む方法について説明します。取得するデータを絞り込むには、WHERE句で条件を指定します。


  • SQL UPDATE文でデータを更新する

    UPDATE文でデータベースに新しいデータを更新する方法を紹介します。自身の値を参照する方法や、副問い合わせの結果をUPDATEする方法も合わせて紹介します。副問い合わせの結果を更新する場合、SETす...


  • SQL 副問い合わせの基本を理解する

    副問い合わせを説明します。副問い合わせとはSQL文の中に入れ子でSQL文を指定することをいいます。


  • SQL SELECT句の基本的な使い方

    SELECT句の基本的な使い方について説明します。


  • SQL SELECTした結果をINSERTで登録する

    SELECT-INSERT文なら、SELECTしたデータをそのまま一気にまとめて登録できるので、実装も簡単ですのでおすすめです。件数分ループでSQLを実行するよりも1回のSQLで一気にまとめて処理でき...


  • SQL ORACLEのROWNUMで行番号を取得する際の注意点

    oracleで行番号を取得する際の基本的な考え方と注意点を紹介します。行番号はROWNUMで取得することができます。注意しなければならないのは、ORDER BYでソートする場合です。ORDER BYは...


  • SQL ROLLUP文で小計行・合計行を出力する (oracle, sql server)

    「社員マスタ」と「売上明細」というテーブルがあります。売上明細テーブルには、社員の売上情報が格納されています。社員ごとに、会社ごとの売上合計を表示し、社員ごとにすべての会社の小計行も出力したい、また最...


  • SQL チューニングでレスポンス改善に効果のあったポイント

    1回のSQLで一気にまとめて取得したほうがレスポンスは早いイメージがありますが、あまり大量のデータを扱うSQLを実行するとサーバーに負荷がかかってしまい、遅くなってしまうことがあります。


  • SQLとプログラミング言語の考え方の違い

    SQLは手続き型言語のように、上から考えるのではなく、集合を操作するという感覚で実装するとうまくいくように思います。また、上からではなく、逆に下から考えるという発送も必要だと思います。1ステップずつ実...