集計関数のCOUNT()は条件にマッチするレコードの件数を数えるのに使われます。
集計関数COUNT()でのNULLの扱いは注意が必要
集計関数のCOUNT()は条件にマッチするレコードの件数を数えるのに使われます。
よくあるパターンのSQL
よくあるのは
SELECT COUNT(*) FROM test_table
のように集計関数COUNT()の引数に「*」を指定するもの。
これは意図通り「条件にマッチする件数」を取得できます。
実は集計関数COUNT()は引数に「*」を指定場合は純粋に引数に「条件にマッチする件数」を取得しますが、「*」ではなく「項目名」を指定した場合はその項目にNULLが含まれているとその行はカウントしません。
以下に具体例で見てみます。
テーブルの準備
データ検索用のテーブルを準備します。
このテーブルは生徒の国語と英語の試験結果を管理します。
受験していない場合はその項目はNULLになります。
--------------------------------------------
--テーブルの準備
--------------------------------------------
CREATE TABLE test_table
(
name VARCHAR(20) NOT NULL --名前
,j_point INT DEFAULT NULL --国語の得点
,e_point INT DEFAULT NULL --英語の得点
)
データの準備
データを準備します。
-------------------------------------------- --データの作成 -------------------------------------------- INSERT INTO test_table VALUES( '太郎さん', 90, 90 ) INSERT INTO test_table VALUES( '次郎さん', 80, 80 ) INSERT INTO test_table VALUES( '三郎さん', 70, 70 ) INSERT INTO test_table VALUES( '四郎さん', 0, NULL ) INSERT INTO test_table VALUES( '五郎さん', 80, 80 ) -------------------------------------------- --データの件数 -------------------------------------------- SELECT * FROM test_table ORDER BY name
上記のデータでは四郎さんは英語は未受験になります。
| name | j_point | e_point |
|---|---|---|
| 五郎さん | 80 | 80 |
| 三郎さん | 70 | 70 |
| 四郎さん | 0 | NULL |
| 次郎さん | 80 | 80 |
| 太郎さん | 90 | 90 |
3.NULLを含めたデータの件数
集計関数COUNT()でNULLを含めた項目をカウントすると以下のようになります。
--------------------------------------------
--レコードの件数
--------------------------------------------
SELECT COUNT(*) AS レコード総数
,COUNT( j_point ) AS 国語の受験者数
,COUNT( e_point ) AS 英語の受験者数
FROM
test_table
| レコード総数 | 国語の受験者数 | 英語の受験者数 |
|---|---|---|
| 5 | 5 | 4 |
国語の受験者数は5人なのに対して英語の受験者数は四郎さんを除いた4人になってます。
集計関数COUNT()はNULLを含む項目が指定された場合はNULLをカウントの対象から外します。
なので、正しい平均点を求めようと思うとCOUNT(*)ではなくCOUNT(国語の受験者数)、COUNT(英語の受験者数)と言うように指定しなければなりません。
--------------------------------------------
--国語の平均点
--------------------------------------------
SELECT SUM( j_point ) / COUNT( j_point )
AS 国語の平均点
SUM( e_point ) / COUNT( e_point )
AS 英語の平均点
FROM
test_table
--------------------------------------------
--テーブルの削除
--------------------------------------------
DROP TABLE test_table
| 国語の平均点 | 英語の平均点 |
|---|---|
| 64 | 80 |
集計関数SUM()やAVG()なども同じ様な動作をします。
