T-SQL - count(*)とcount(カラム名)の違い

知らなかったのでメモ。

count(*)は全行数を取得するのに対して、count(カラム名)はnullを除く行数を取得します。

サンプルクエリを書いて確認しておきましょう。

select
    -- nullに関係なく全行数を取得
    count(*) as [count(*)],
    -- nullを除く行数を取得
    count(Value) as [count(Value)]
from (values
    (1, 100),
    (2, 200),
    (3, 200),
    (4, null),
    (5, 300),
    (6, 200)) as Test(Id, Value);

-- 行は全部で6、nullを除くと5
/*
count(*)    count(Value)
----------- ------------
6           5
*/

おまけ

countだけでなくsumやavgなどの関数もnullを無視して集計します。

select
    count(Value) as [count(Value)],
    sum(Value) as [sum(Value)],
    avg(Value) as [avg(Value)]
from (values
    (1, 100),
    (2, 200),
    (3, 200),
    (4, null),
    (5, 300),
    (6, 200)) as Test(Id, Value);

/*
count(Value) sum(Value)  avg(Value)
------------ ----------- -----------
5            1000        200
*/

おまけ2

nullの行しか存在しない場合はどうなるんだろうと思って、countやsumなどの関数を試しました。次のような結果になります。

select
    count(Value) as [count(Value)],
    sum(Value) as [sum(Value)],
    avg(Value) as [avg(Value)],
    min(Value) as [min(Value)],
    max(Value) as [max(Value)]
from (values
    -- nullの行が1つ
    (cast(null as int))) as Test(Value);

/*
count(Value) sum(Value)  avg(Value)  min(Value)  max(Value)
------------ ----------- ----------- ----------- -----------
0            NULL        NULL        NULL        NULL
警告: NULL 値は集計またはその他の SET 演算で削除されました。
*/

ん?警告?

参考

COUNT (Transact-SQL) | Microsoft Docs