今回はCOUNT関数を使うとき個人的にこれだけは覚えておきたい2つの基礎をまとめておきます。
前提
環境:PostgreSQL17
で実施しています。
また、今回は前提として簡単なテーブルとデータを用意してます。
実際に同じ条件で試したい場合は、最初にテーブルとデータを作ってください。
自分の環境で試す場合は、不要です。
CREATE TABLE test(type INTEGER, name VARCHAR (15) NOT NULL);
insert
into test(type, name)
values
(1, '名前1')
, (1, '名前2')
, (1, '名前3')
, (2, '名前4')
, (2, '名前5')
, (2, '名前6')
, (null, '名前7');
関数の引数で集計結果が変わる
COUT(*)としがちですが、引数にはしっかり意味があります。
引数によってSQLの結果が変わることを覚えておきましょう。
パラメータ | 説明 |
---|---|
* | NULLを含めたレコード数 |
1 | NULLを含めたレコード件数 |
カラム名 | NULLを含まないレコード数 |
DISTINCT カラム名 | NULLと重複を含まないレコード件数 |
実際にSQLを実行すると以下のようになります。
結果を見て分かるように「*」「1」とした場合、NULLのレコードも含んでしまうこと重要です。
用途によって、しっかりと理解して使い分けるようにしましょう。
SELECT COUNT(*) FROM test;
---------------------
count
7
SELECT COUNT(1) FROM test;
---------------------
count
7
SELECT COUNT(type) FROM test;
---------------------
count
6
SELECT COUNT(DISTINCT(type)) FROM test;
---------------------
count
2
条件をつけて集計する
COUNT関数では条件をつけて集計することもできます。
引数で条件をつけることができます。今回はCASEを使う方法と使わない方法を載せておきます。
①CASEを使わない
以下のように条件をつけることで、「typeが1のレコードの件数をカウント」することができます。
-- typeが1のレコードの件数をカウント
SELECT COUNT(type=1 OR NULL) FROM test;
---------------------
count
3
ここでのポイントはSQLでは3値論理が採用されていることです。
3値論理は下表を参考にしてください。
そのため、「typeが1のレコードの件数をカウント」するために条件に「OR NULL」を追加しています。
a | b | a AND b | a OR b |
---|---|---|---|
TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | FALSE | TRUE |
TRUE | NULL | NULL | TRUE |
FALSE | FALSE | FALSE | FALSE |
FALSE | NULL | FALSE | NULL |
NULL | NULL | NULL | NULL |
ちなみに、「OR NULL」をつけない場合、このようになります。
-- typeが1のレコードの件数をカウント
SELECT COUNT(type=1) FROM test;
---------------------
count
6
②CASEを使う
引数にCASEを使うこともできます。
引数にCASEを使って条件に一致する場合はTrue、一致しない場合はNULLとすることで「typeが1のレコードの件数をカウント」することができます。
-- typeが1のレコードの件数をカウント
SELECT COUNT(CASE WHEN type=1 THEN TRUE ELSE NULL END) FROM test;
---------------------
count
3
この時、NULLではなく、Falseにしてもいいのではと思うかもしれませんが、Falseにすると正しい結果を取得できないので注意です。
-- typeが1のレコードの件数をカウント
SELECT COUNT(CASE WHEN type=1 THEN TRUE ELSE FALSE END) FROM test;
---------------------
count
7