1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

システム改修の効果測定や新事業の展開拡大の効果予測など、KPI確認のために最近叩く回数も増えてきているので今更感を感じながらもメモがてら書いていきます。


一定条件のレコードのみをCOUNTしようとしてうまく行かなかった話

このようなsalesテーブルが存在すると仮定する。

dates number res mvp
2017-01-01 00:00:00 2562 false NULL
2017-02-01 00:00:00 2250 false NULL
2017-03-01 00:00:00 2768 false NULL
2017-04-01 00:00:00 2468 false NULL
2017-05-01 00:00:00 1637 false NULL
2017-06-01 00:00:00 1672 false NULL
2017-07-01 00:00:00 2339 false NULL
2017-08-01 00:00:00 2585 false NULL
2017-09-01 00:00:00 2200 false NULL
2017-10-01 00:00:00 2600 false NULL
2017-11-01 00:00:00 3020 true A
2017-12-01 00:00:00 2869 true B

resカラムの値を利用し、目標を達成した数をCOUNTするため、
以下のようなSQLを叩く。

SELECT COUNT(res='true') AS "success",
       COUNT(res='false') AS "failed"
  FROM sales

結果

success failed
12 12

条件問わず全部カウントされている...

公式ページ
https://www.postgresql.jp/document/7.4/html/functions-aggregate.html

expressionが非NULL値を持つ入力値の個数

null以外全てを数える模様。
ならば、条件を通す時に指定した値以外はNULLCOUNTに渡すようにすれば良い。

SELECT COUNT(
         (CASE
            WHEN res='true' THEN res
            ELSE NULL
         END)
       ) AS "success",
       COUNT(
         (CASE
            WHEN res='false' THEN res
            ELSE NULL
         END)
       ) AS "failed"
  FROM sales
success failed
2 10

ok

では、今度は逆にNULLの数をカウントしてみる。
ということで、今度は以下SQLを実行

SELECT COUNT(
        (CASE
            WHEN mvp=NULL THEN mvp
            ELSE 'true'
        END)
      ) AS "NOT NULL",
      COUNT(
        (CASE
            WHEN mvp!=NULL THEN mvp
            ELSE 'true'
        END)
      ) AS "IS NULL"
  FROM sales;

結果

NOT NULL IS NULL
12 12

ん? やはり何かおかしい...?

ググってみると、SQLでは3値論理を採用し、NULLを第3の真理値として扱っているらしい。
よって、条件などで利用する際にはIS NULLを利用する必要があるとのこと。

ということで条件式を一部変更

SELECT COUNT(
        (CASE
            WHEN mvp IS NULL THEN mvp
            ELSE 'true'
        END)
      ) AS "NOT NULL",
      COUNT(
        (CASE
            WHEN mvp IS NOT NULL THEN NULL
            ELSE 'true'
        END)
      ) AS "IS NULL"
  FROM sales;

結果

NOT NULL IS NULL
2 10

ok


まとめ

月並みですがNULLの扱いに気をつけましょう

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?