プログラミング

【入門】PostgreSQLで条件付きのCOUNTを使う方法

2021年10月14日

SQLで定番のCOUNT関数。

PostgreSQL(MySQL)では条件を付けてカウントすることができます。

条件付きでCOUNT方法を画像付きで解説します。

対象者

  • PostgreSQLの利用者
  • PostgreSQLで条件付きの件数を取得したい人

例題①:COUNT関数で条件を指定するSQL

例として、col_1が100のレコード数を取得します。

  • 対象テーブル
    以下のテーブルを用意します。
テストデータ
CREATE TABLE IF NOT EXISTS test
(
    id integer,
    col_1 character varying(10) COLLATE pg_catalog."default",
    col_2 character varying(10) COLLATE pg_catalog."default",
    col_3 character varying(10) COLLATE pg_catalog."default"
)
INSERT INTO test(
	id, col_1, col_2, col_3)
	VALUES (1,'100','aaaa','bbbb'),(2,'100','abcd','efgh'),(3,'200','dddd','eeee'),(4,'300','gggg','hhhh');
  • col_1が100のレコード件数を取得するSQL
    想定件数:2

以下のSQLを実行します。

SELECT COUNT(col_1='100'or null) from test;
COUNTの例

ポイント

ポイントはcol_1='100'or nullの部分です。

なんで、 col_1='100' でないのかと疑問に感じるかと思います。

試しに col_1='100' のみを条件にすると結果は4となります。

これは、count( expression )はNULL以外をカウントするためです。

公式リファレンスにあるとおり、count(expression)の戻り値はbigint型となります。

つまり、一致する場合は1、一致しない場合は0が返却されます。

NULL以外をカウントするので、一致する・一致しないどちらもカウントしてしまい結果が4となります。

そこで、三値論理を使い正しい値を取得するようにします。

三値論理とは、通常の真 (true) と偽 (false) から成る真偽値の他に、第3の真理値を持つ論理体系です。

SQLにはこの三値論理が採用されています。

三値論理についてはqiitaの記事を参考にしてください。

PostgreSQLの三理論値の真理値表は公式のリファレンスに書かれています。

この三値論理を使うことになるので、条件はcol_1='100'or nullとなります。

例題②:COUNT関数で条件 を指定するSQL (応用編)

続けて、応用編として三値論理をつかって以下の条件を満たすSQLを考えます。

※ 三理論値を試すために、イレギュラーなSQLにしています。

  1. col_1が100かつcol2がaaaaのレコード件数を取得
    想定件数:1
  2. col_1が100かつcol2がaaaa以外のレコード件数を取得
    想定件数:3

テストデータは、 例題①と同じデータを使います

テストデータ

真理値表

3行目の条件に一致するようにSQLを作るとこのようになります。

真理値表のとおり、ORとANDで結果が逆になっていることが分かります。

  • col_1が100かつcol2がaaaa以外のレコード件数を取得
ab 演算子
col_1='100' and col_2 = 'aaaa'NULLor
SELECT COUNT((col_1='100' and col_2 = 'aaaa') or null) from test;
応用例①の結果


3行目の条件に一致するようにSQLを作るとこのようになります。

ab 演算子
col_1='100' and col_2 = 'aaaa'NULLand
SELECT COUNT((col_1='100' and col_2 = 'aaaa') and null) from test;
応用例②の結果

まとめ

三値論理は正直とっつきにくいと思います。

WHERE句で条件を絞って取得もできますが、サクッと条件に沿ったレコード件数を取得したいときにはCOUNTに条件を付けることができるのはとても便利です。

是非、手を動かして試してみてください。

-プログラミング