【SQL実践|実務向け】SQLiteで「行数」を正しくカウントする―count()とcount(カラム名)の決定的な違い

導入

データベース管理において、テーブル内のレコード数を把握することは、データ分析やシステムの状態監視の基本です。しかし、SQLのcount関数をなんとなく使っていると、意図しない集計結果を招くリスクがあります。特に、NULL値の扱いによって「想定していた数値と合わない」というトラブルは現場で頻発します。今回は、count関数の正確な挙動と、実務で安全に使うための知識を解説します。

基礎知識

count関数は、指定した範囲内の行数を数える集計関数です。大きく分けて以下の2つの指定方法があります。

count(): テーブル内の全行数をカウントします。NULL値が含まれていても、1行として数えます。
count(カラム名): 指定したカラムの値がNULLではない行のみをカウントします。

重要な点は、count(カラム名)は「データが存在する行」を数えるものであり、単なる「テーブルの行数」を求めるものではないという点です。

実装/解決策

実務では、単なる全行取得だけでなく、カテゴリごとの集計(GROUP BY)や、特定条件下のデータ件数取得でこの関数を多用します。NULLが含まれるカラムに対してcount(カラム名)を使うと、カウント漏れが発生するため、純粋にレコード数を数えたい場合は原則としてcount()を使用してください。

サンプルプログラム

以下は、ユーザーテーブルを作成し、NULL値を含んだデータでカウントの挙動を確認するコードです。

— テーブル作成
create table user(id integer, name text, address text, gender text);

— データ挿入(4件目のaddressがNULL)
insert into user values(1, ‘Honda’, ‘Tokyo’, ‘Man’);
insert into user values(2, ‘Suzuki’, ‘Nagoya’, ‘Woman’);
insert into user values(3, ‘Kojima’, ‘Kyoto’, ‘Man’);
insert into user values(4, ‘Utada’, NULL, ‘Man’);
insert into user values(5, ‘Sakai’, ‘Tokyo’, ‘Woman’);

— 1. 全行をカウント(結果: 5)
select count() as total_count from user;

— 2. カラムを指定してカウント(結果: name=5, address=4 ※NULLが除外される)
select count(name) as name_count, count(address) as address_count from user;

— 3. 性別ごとにグループ化してカウント(結果: Man=3, Woman=2)
select gender, count() as group_count from user group by gender;

応用・注意点

現場での運用において、以下の点に注意してください。

パフォーマンスへの意識:
非常に大きなテーブルに対してcount()を実行すると、ストレージI/Oが発生し、レスポンスが悪化する場合があります。頻繁にカウントが必要な場合は、トリガーを用いたカウント用テーブルの作成や、アプリケーション側でのキャッシュを検討してください。

NULLの扱いを仕様化する:
「このカラムがNULLのデータは集計対象外であるべきか」を事前に定義することが重要です。もしNULLを含めて件数を出しつつ、特定条件でフィルタリングしたい場合は、WHERE句を適切に組み合わせるようにしましょう。

DISTINCTとの併用:
指定したカラムの「ユニークな値の数」を知りたい場合は、count(distinct カラム名)を使うことで重複を除いた件数を得ることが可能です。これも実務では多用するテクニックですので、あわせて覚えておきましょう。

コメント

タイトルとURLをコピーしました