SQLでデータに対して何らかの操作や計算を行うには、「関数」を使います。関数とは、ある値を入力すると、それに対応する値が出力されるものです。

例えば、「ある列の値を合計する」という計算を行うときは、SUM関数を使用します。他にもSQLには集計用の関数が多く用意されていますが、まずは下表の5つを覚えておきましょう。

COUNTテーブルのレコード数(行数)を求める
SUMテーブルの数値列のデータを合計する
AVGテーブルの数値列のデータを平均する
MAXテーブルの任意の列のデータの最大値を求める
MINテーブルの任意の列のデータの最小値を求める

このような集計用の関数を「集約関数」または「集合関数」と言います。集約とは「複数行を1行にまとめる」という意味です。

以下のデータが格納される表を使って、以降の例を示します。

SELECT name, department_id
FROM Employees;
実行結果
    name    | department_id
------------+---------------
 山田太郎   | 0010
 佐藤達弘   | 0050
 木村幸平   | 0050
 神埼恵美   | 0100
 高木龍之介 |
 青木和也   |
(6 行)

COUNT関数

SELECTの後にCOUNT(*)と指定すると、レコード数(行数)を求められます。

SELECT COUNT(*)
FROM Employees
実行結果
 count
-------
     6
(1 行)

NULLが含まれる場合、結果が変わります。NULLが含まれる列をCOUNT関数にかけるとNULLはカウントされません。

SELECT COUNT(department_id)
FROM Employees;
実行結果
 count
-------
     4
(1 行)

このように、テーブルの全行を数えたい場合はCOUNT(*)を使用し、ある列を対象にNULLの行を除外して数えたい場合は、COUNT(department_id)のように、COUNT関数の引数に列を限定して指定します

SUM関数

SUM(列名)と指定すると、その列名の合計値が求められます。NULLは計算対象外となります。

SELECT SUM(salary)
FROM Employees;
実行結果
   sum
---------
 1690000
(1 行)

上記では全従業員の給与額の合計値を算出しています。

AVG関数

AVG(列名)と指定すると、その列名の平均値が求められます。NULLは計算対象外となります。

SELECT AVG(salary)
FROM Employees;
実行結果
         avg
---------------------
 281666.666666666667
(1 行)

平均値は「値の合計/値の個数」という一般的な式で算出されます。

MAX関数、MIN関数

MAX(列名)と指定すると、その列名の最大値が求められ、MIN(列名)と指定すると、その列名の最小値が求められます。

SELECT MAX(salary), MIN(salary)
FROM Employees;
実行結果
  max   |  min
--------+--------
 500000 | 210000
(1 行)

使い方はSUM関数、AVG関数と同じですが、それらの関数と異なる点があります。SUM関数、AVG関数はその特性上、数値型の列に対してのみしか使えませんが、MAX関数、MIN関数は原則、どのようなデータ型にも使用できます。

例えば、日付型の列を指定した場合、実行結果は以下のようになります。

SELECT MAX(hire_data), MIN(hire_data)
FROM Employees;
実行結果
    max     |    min
------------+------------
 2018-04-01 | 1984-04-01
(1 行)

日付型では、最大が最新日付、最小が最古日付となっていることがわかります。

なお、すべての集約関数は、引数に列名が指定された場合、計算前にNULLを除外することになっています。以前の記事で、四則演算の中にNULLが含まれていた場合、すべてNULLになるということを書きましたが、集約関数は前述のとおり、計算前にNULLは除外されるため、NULLにはならず、すべて無視されます。

集約関数でDISTINCTを使用する

DISTINCTを使用して重複値を除外し、集約関数を使うこともできます。
例えば、職種ID(job_id)の種類の数を求めたい場合、単にCOUNT関数を使用しただけでは行数が求められるだけで、期待した値を求めることはできません。

SELECT job_id
FROM Employees;
実行結果
  job_id
----------
 AD_PRES
 IT_PROG
 IT_PROG
 ST_CLERK
 IT_PROG
 ST_TRAIN
(6 行)

上記表をCOUNT(job_id)とした場合、「6」が算出されます。そうではなく、「値の種類」の個数を求めたい場合は、以下のようにDISTINCTを使用します。

SELECT COUNT(DISTINCT job_id)
FROM Employees;
実行結果
 count
-------
     4
(1 行)

COUNT関数の引数にDISTINCTキーワードを指定することで、重複した値を取り除いた行数が求められます。、