Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

平均を取得するAVG関数

SQLでレコードの平均値を取得したい場合は「AVG関数」を使います。

使う場合は、次のように記述しましょう。

SELECT AVG(カラム名) FROM テーブル名;

実際に、次のようなテーブルを作成して確認してみます。

mydb=# CREATE TABLE score_tb(class varchar(10), name varchar(20), score integer);
CREATE TABLE

なお、ここでは「PostgreSQL」を使用しました。

インストール方法や使い方を知りたい場合は、下記の記事を参考にしてみてください。

【関連記事】
▶︎PostgreSQLのインストールからテーブル作成まで解説【初心者向け】

そして、テーブル内には次のデータを追加しました。

mydb=# INSERT INTO score_tb VALUES('1-1', 'Satou', 67);
INSERT 0 1
mydb=# INSERT INTO score_tb VALUES('1-2', 'Yamada', 73);
INSERT 0 1
mydb=# INSERT INTO score_tb VALUES('1-1', 'Tanaka', 89);
INSERT 0 1
mydb=# INSERT INTO score_tb VALUES('1-3', 'Yokota', 56);
INSERT 0 1
mydb=# INSERT INTO score_tb VALUES('1-2', 'Itou', 91);
INSERT 0 1

この全データに対してAVG関数で平均を取得してみましょう。

mydb=# SELECT AVG(score) FROM score_tb;
         avg         
---------------------
 75.2000000000000000
(1 row)

実際に計算機で計算しても「75.2」となり、ちゃんと平均が取得できているのがわかります。

AVG関数は条件を指定しても取得可能です。

平均を条件付きで取得する方法

次に、条件を指定しつつデータを取得する方法を見ていきましょう。

特定の条件に一致するデータの平均を取得(WHERE)

今回作成したテーブルの例だと「指定したcalssの平均値を取得したい」という場合もあるでしょう。

こんな風に特定の条件で平均を求めたい場合は、「WHERE句」を使って指定します。

記述方法は次の通りです。

SELECT AVG(カラム名) FROM テーブル名 WHERE 条件文;

サンプルで平均の求め方を見てみましょう。

mydb=# SELECT AVG(score) FROM score_tb WHERE class = '1-1';
         avg         
---------------------
 78.0000000000000000
(1 row)

ここでは、classカラムが「1-1」であるデータの平均値を取得しました。

計算結果を確認してみると、ちゃんと平均を取得できているのがわかります。

複数行のデータの平均を取得(GROUP BY)

「classが1-1、1-2、1-3ごとにまとめて平均を取得したい」場合は、「GROUP BY句」が使えます。

記述方法は次の通りです。

SELECT AVG(カラム名) FROM テーブル名 GROUP BY カラム名;

こちらもサンプルコードで表示を確認してみましょう。

mydb=# SELECT class, AVG(score) FROM score_tb GROUP BY class;
 class |         avg         
-------+---------------------
 1-2   | 82.0000000000000000
 1-3   | 56.0000000000000000
 1-1   | 78.0000000000000000
(3 rows)

平均値だけだとどのclassのデータかわかりづらいため、SELECTに「class」を追加しました。

このようにclassごとに平均が求められました。

ただ、classが「1-2」「1-3」「1-1」と言う順番になっていて少し気持ち悪いですよね。

classの順番を変更したい場合は「ORDER BY句」も組み合わせれば次のようにきれいに表示できますので参考までに。

mydb=# SELECT class, AVG(score) FROM score_tb GROUP BY class ORDER BY class;
 class |         avg         
-------+---------------------
 1-1   | 78.0000000000000000
 1-2   | 82.0000000000000000
 1-3   | 56.0000000000000000
(3 rows)

複数列の平均を取得する

複数列の平均を取得する方法を確認してみましょう。

先ほどのテーブルに「point」カラムを追加し、それぞれのデータに値を次のように挿入しました。

mydb=# SELECT * FROM score_tb;
 class |  name  | score | point 
-------+--------+-------+-------
 1-1   | Satou  |    67 |   133
 1-2   | Yamada |    73 |   173
 1-1   | Tanaka |    89 |   220
 1-3   | Yokota |    56 |   101
 1-2   | Itou   |    91 |   149
(5 rows)

このテーブルの「score」と「point」カラムの平均をclassごとに取得してみます。

mydb=# SELECT class, AVG(score) AS score_ave, AVG(point) AS point_ave FROM score_tb GROUP BY class ORDER BY class;
 class |      score_ave      |      point_ave       
-------+---------------------+----------------------
 1-1   | 78.0000000000000000 | 176.5000000000000000
 1-2   | 82.0000000000000000 | 161.0000000000000000
 1-3   | 56.0000000000000000 | 101.0000000000000000
(3 rows)

このように「score」と「point」カラムの平均を取得できました。

 

また、「複数のカラムの値を合計した平均」を取得したい場合は、AVG関数を使わずに次のような記述で取得可能です。

mydb=# SELECT class, name, score, point, (score+point)/2 AS avg FROM score_tb GROUP BY class, name, score, point;
 class |  name  | score | point | avg 
-------+--------+-------+-------+-----
 1-2   | Yamada |    73 |   173 | 123
 1-1   | Satou  |    67 |   133 | 100
 1-3   | Yokota |    56 |   101 |  78
 1-2   | Itou   |    91 |   149 | 120
 1-1   | Tanaka |    89 |   220 | 154

純粋に「score」と「point」カラムの値を足して2で割っています。

これで2つ(複数)のカラムの平均値を求められます。

ただし、データにNULLが入っていると平均値もNULLになってしまうため、この辺りは別途処理が必要です。

詳しくは「平均の取得でNULLがある場合」で解説します。

平均値の小数点以下を切り捨てる方法

AVG関数を使って平均を取得すると、小数点以下まで表示されていました。

この小数点以下を切り捨てる場合は「TRUNC関数」を使います。(MySQLの場合は「TRUNCATE関数」になります)

実際に小数点以下の表示がどのようになるのか確認してみましょう。

今度は、「score_tb」テーブルに「height」カラムを追加しました。

mydb=# SELECT * FROM score_tb;
 class |  name  | score | point | height 
-------+--------+-------+-------+--------
 1-1   | Satou  |    67 |   133 |  182.4
 1-1   | Tanaka |    89 |   220 |  173.7
 1-3   | Yokota |    56 |   101 |  175.9
 1-2   | Itou   |    91 |   149 |  170.3
 1-2   | Yamada |    74 |   173 |  179.6
(5 rows)

この「height」カラムの平均値を「class」カラムごとに取得してみます。

mydb=# SELECT class, AVG(height) FROM score_tb GROUP BY class;
 class |  avg   
-------+--------
 1-2   | 174.95
 1-3   |  175.9
 1-1   | 178.05
(3 rows)

このように、小数点以下の値まで取得できました。

では、TRUNC関数を使って平均を求めてみます。

mydb=# SELECT class, TRUNC(AVG(height)) FROM score_tb GROUP BY class;
 class | trunc 
-------+-------
 1-2   |   174
 1-3   |   175
 1-1   |   178
(3 rows)

小数点以下が切り捨てられ、整数で値が表示されているのがわかります。

平均値を四捨五入する方法

小数点以下を切り捨てではなく、四捨五入したい場合は「ROUND関数」を使いましょう。

mydb=# SELECT class, ROUND(AVG(height)) FROM score_tb GROUP BY class;
 class | round 
-------+-------
 1-2   |   175
 1-3   |   176
 1-1   |   178
(3 rows)

このように四捨五入した値が取得できます。

平均の取得でNULLがある場合

AVG関数でカラムの値を取得する際に「NULL」が入っている場合、NULLは無視されます。

こちらもサンプルで表示を確認してみましょう。

データに「score」カラムがNULLのデータを追加しました。

mydb=# SELECT * FROM score_tb;
 class |   name    | score | point | height 
-------+-----------+-------+-------+--------
 1-1   | Satou     |    67 |   133 |  182.4
 1-1   | Tanaka    |    89 |   220 |  173.7
 1-3   | Yokota    |    56 |   101 |  175.9
 1-2   | Itou      |    91 |   149 |  170.3
 1-2   | Yamada    |    74 |   173 |  179.6
 1-3   | Hashimoto |       |    15 |  154.7
(6 rows)

では、次の記述で平均値を取得してみましょう。

mydb=# SELECT class, AVG(score) FROM score_tb GROUP BY class;
 class |         avg         
-------+---------------------
 1-2   | 82.5000000000000000
 1-3   | 56.0000000000000000
 1-1   | 78.0000000000000000
(3 rows)

このように、NULLは無視されて平均が求められています。

ただし、データがNULLしかない場合は平均値もNULLになります。

mydb=# SELECT class, AVG(score) FROM score_tb GROUP BY class;
class |         avg         
-------+---------------------
 1-2   | 82.5000000000000000
 1-4   |                    
 1-3   | 56.0000000000000000
 1-1   | 78.0000000000000000
(4 rows)

 

では「複数列の平均を取得する」で解説した「score」と「point」カラムにNULLがあった場合の平均の求め方も見ていきましょう。

これを実現する1つの方法に「COALESCE関数」を使う方法があります。

COALESCE関数は、NULLの代替値を取得する関数です。

詳しい内容は次の記事で解説していますので、知りたい方は参考にしてみてください。

【関連記事】
▶︎SQL coalesce 値がNULLの場合の代替値を返す 簡易版のNVLやNULLIFが使えるDBもあり

ではサンプルで表示を確認してみます。

mydb=# SELECT class, name, score, point, COALESCE((score+point)/2, score, point) AS avg FROM score_tb GROUP BY class, name, score, point;
 class |   name    | score | point | avg 
-------+-----------+-------+-------+-----
 1-3   | Hashimoto |       |    15 |  15
 1-1   | Satou     |    67 |   133 | 100
 1-3   | Yokota    |    56 |   101 |  78
 1-2   | Itou      |    91 |   149 | 120
 1-4   | Minami    |       |   155 | 155
 1-1   | Tanaka    |    89 |   220 | 154
 1-2   | Yamada    |    74 |   173 | 123
(7 rows)

このように、scoreがNULLである「Hashimoto」と「Minami」の平均値も取得できていますね。

AVG関数を使う場合は問題ありませんが、そうでない場合はNULLを考慮したSQLクエリを記述しましょう。

まとめ

SQLの平均に関する関数や取得方法について解説しました。

DB操作でデータの平均を求める機会は多くあると思います。

ぜひこの記事で平均を取得する方法の参考にしてください!

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。