集計関数COUNT()でのNULLの扱い

プログラミング SQL Server

集計関数の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()なども同じ様な動作をします。

タイトルとURLをコピーしました