【SQL】COUNT(*)と COUNT(カラム名)の違い

【SQL】COUNT(*)とCOUNT(カラム名)の違い

どうも、hosigakiです!
今日は華金ですね、皆さん一週間お疲れ様です!(^^)/

SQLを勉強したての頃、COUNT(*)COUNT(カラム名)の違いが分からず苦戦した記憶があります。ということで、今回はこれらの違いについて説明したいと思います!

二つの違いを一言で言うと

COUNT(*)とCOUNT(カラム名)の違いを一言で言うと、

NULLをカウントするか否か

に尽きます!

COUNT(*)はNULLをカウントして、COUNT(カラム名)はNULLをカウントしない、という違いがあります!

クエリで違いを調べてみよう!

実際にクエリで二つの違いを確かめてみましょう!

今回は、以下のシンプルなテーブルを使って、ユーザー数をカウントするとします。

idname
1太郎
2よしお
3SAKI
4
5ジム
usersテーブル

この時、クエリとその抽出結果の組み合わせは、それぞれ以下のようになります。

SELECT
    COUNT(*)
FROM
    users

/* 抽出結果: 5 */
SELECT
    COUNT(name)
FROM
    users

/* 抽出結果: 4 */

上のクエリではCOUNT(*)を使っているため、レコードにNULLがあるか否かに関係なく、全てのレコードを数えます。

対して、下のクエリではCOUNT(name)を使っており、nameカラムのNULLの値がカウントされません。

COUNT(カラム名)の使いどころ

二つの違いが分かったところで、恐らく皆さん、

COUNT(*)はよく聞くけど、COUNT(カラム名)を使う場面ってあるんかな~...

と思ってるかもなので、ここでは COUNT(カラム名) の使いどころについて軽く触れたいと思います!

重複レコードがある時に、COUNT(DISTINCT カラム名) を使う

例えば、以下の二つのテーブルを使って、ユニーク登録ユーザー数とユニーク購入ユーザー数をカウントするとします。

idname
1太郎
2よしお
3SAKI
usersテーブル
iditemuser_id
1干し柿1
2干し柿1
3干し柿まんじゅう2
purchasesテーブル

usersテーブルに対して、purchasesテーブルをLEFT OUTER JOINで結合すると、次のようなテーブルになります。

idnameiditemuser_id
1太郎1干し柿1
1太郎2干し柿1
2よしお3干し柿まんじゅう2
3SAKI
purchasesテーブル側に、 user_id=1 のレコードが二つあるので、
usersテーブル側の id=1 のレコードが重複して作成されています。

この状態で、例えば登録者数をCOUNT(*)で算出しようとすると、重複レコードが数えられて 4 が算出されてしまいます。
そこで、COUNT(DISTINCT カラム名) の出番です!

SELECT
    COUNT(DISTINCT u.id) AS user_count,
    COUNT(DISTINCT p.user_id) AS purchase_user_count
FROM
    users AS u
    LEFT OUTER JOIN purchases AS p
        ON u.id = p.user_id

登録者数については、COUNT関数の中身で、DISTINCT u.nameによってユーザー名をユニークな値のみに絞り、その数を数えています。
購入者数についても同様に、p.user_idのユニークな値をカウントしています。

COUNT(*) COUNT(カラム名) は、どちらも使い分けられるようになると、データ分析の効率がグッとUPするのでお勧めです!

ここまで読んでいただきありがとうございます!
また次の記事でお会いしましょう(^^)/

-SQL
-, , , ,