1. はじめに
データベースを運用していると、「登録された国の種類はいくつあるのか?」や「ユニークなメールアドレスの件数を知りたい」といった場面に遭遇することがあります。
このような場合、MySQLのCOUNT(DISTINCT column_name)を使うことで、重複を排除しながらデータの件数を取得できます。 本記事では、以下の内容を詳しく解説します。COUNT()とDISTINCTの基本COUNT(DISTINCT column_name)の正しい使い方- 複数カラムのユニークデータのカウント方法
COUNT(DISTINCT)のパフォーマンスを向上させる方法
初心者の方でも理解しやすいように、具体例やSQLクエリを交えながら説明するので、ぜひ最後までお読みください。
2. MySQLでデータを数える基本(COUNT)
データベースで情報を分析する際、最も基本となるのがCOUNT()関数です。
まずはCOUNT()の基本的な動作を理解しましょう。2.1 COUNT(*)とCOUNT(column_name)の違い
MySQLのCOUNT()関数には、以下の2つの使い方があります。| COUNT関数 | 説明 |
|---|
COUNT(*) | テーブル内の全レコード数をカウント(NULL含む) |
COUNT(column_name) | 特定のカラムのNULL以外の値をカウント |
2.2 COUNT()の基本例
ここでは、以下のusersテーブルを例に説明します。| id | name | email | country |
|---|
| 1 | 太郎 | taro@example.com | 日本 |
| 2 | 花子 | hanako@example.com | 日本 |
| 3 | ジョン | NULL | アメリカ |
| 4 | 田中 | tanaka@example.com | 日本 |
① テーブル全体のレコード数を取得
SELECT COUNT(*) FROM users;
→ 結果: 4(全レコードの数)② NULLを除いた特定カラムの件数を取得
SELECT COUNT(email) FROM users;
→ 結果: 3(NULL以外のemailの件数) 💡 ポイント:COUNT(*) は NULLを含む 全レコード数を取得します。COUNT(email) は NULLを除外 してカウントします。

3. 重複を除いてデータを取得する(DISTINCT)
データの集計をする際、「ユニークな値のみを取得したい」ケースも多いでしょう。
このような場合に役立つのが、DISTINCT です。3.1 DISTINCTの基本
DISTINCTは、指定したカラムの重複データを排除して結果を取得するために使用されます。基本構文
SELECT DISTINCT column_name FROM table_name;
3.2 DISTINCTの使用例
以下のSQLクエリを実行すると、ユーザーが登録したユニークな国名のリストを取得できます。SELECT DISTINCT country FROM users;
→ 結果:3.3 DISTINCTとGROUP BYの違い
| 機能 | DISTINCT | GROUP BY |
|---|
| 目的 | ユニークな値を取得 | グループごとの集計を行う |
| 使い方 | SELECT DISTINCT column_name | SELECT column_name, COUNT(*) GROUP BY column_name |
| 例 | ユニークな国を取得 | 各国のユーザー数をカウント |
💡 ポイント:DISTINCTは重複データを単純に除去する。GROUP BYはデータをグループ化して、集計関数と組み合わせて使う。
4. COUNT(DISTINCT column_name)の使い方
COUNT(DISTINCT column_name)を使うことで、ユニークな値の数を取得できます。4.1 COUNT(DISTINCT)の基本
基本構文
SELECT COUNT(DISTINCT column_name) FROM table_name;
4.2 COUNT(DISTINCT)の使用例
SELECT COUNT(DISTINCT country) FROM users;
→ 結果: 2(「日本」と「アメリカ」の2種類)4.3 条件付きでCOUNT(DISTINCT)を使う
SELECT COUNT(DISTINCT email) FROM users WHERE country = '日本';
→ 結果: 2(日本に登録されているユニークなemailの数) 💡 ポイント:COUNT(DISTINCT column_name) は、NULL値を除外 してユニークなデータの件数を取得する。- WHERE句を活用することで、特定の条件を満たすデータの件数をカウント可能。
5. 複数カラムでのCOUNT(DISTINCT)の使用
MySQLではCOUNT(DISTINCT column1, column2)の直接使用は不可です。その代わり、CONCAT()を使ってカラムを結合し、1つの値として扱う方法があります。5.1 COUNT(DISTINCT column1, column2)が使えない理由
MySQLでは、COUNT(DISTINCT column1, column2) のように 複数のカラムを対象に直接COUNT(DISTINCT)を適用することはできません。 これはMySQLの制限によるものです。5.2 複数カラムのユニーク値をカウントする方法
複数カラムの組み合わせでユニークなデータ数を取得するには、CONCAT()を使ってカラムを結合し、それをCOUNT(DISTINCT)に適用する方法が一般的です。使用例: 国と都市の組み合わせでユニークな件数を取得
SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;
💡 ポイント:CONCAT(column1, '-', column2) を使うことで、複数カラムを結合してユニークな値を作成できる。COUNT(DISTINCT CONCAT(...)) を使うことで、複数カラムの組み合わせごとのユニークデータを取得可能。
6. COUNT(DISTINCT)のパフォーマンスチューニング
COUNT(DISTINCT)はパフォーマンスに影響を与える場合があるため、最適化が必要です。
大量のデータセットで使用する場合、インデックスの活用や代替手法を検討すると良いでしょう。6.1 COUNT(DISTINCT)が遅くなる理由
- MySQLは、
DISTINCTを適用するために全レコードをスキャンすることが多い。 - インデックスが適切に設定されていないと、処理速度が遅くなる。
- データの重複が多い場合、計算負荷が増大する。
6.2 COUNT(DISTINCT)の高速化のためのインデックス最適化
データ量が多い場合、対象カラムにインデックスを追加することで検索速度を向上させることができます。インデックスの追加方法
ALTER TABLE users ADD INDEX (country);
インデックスを使用してクエリの実行計画を確認する
EXPLAIN SELECT COUNT(DISTINCT country) FROM users;
💡 ポイント:EXPLAIN を使うことで、MySQLがどのようにクエリを処理しているか確認できる。- インデックスを適用すると、フルテーブルスキャンを回避し、検索が高速化される可能性がある。
6.3 GROUP BY + COUNT の代替手法
データの集計によっては、GROUP BY を使った方法のほうが高速になる場合があります。使用例: GROUP BY を使ってユニークデータをカウント
SELECT country, COUNT(*) FROM users GROUP BY country;
💡 ポイント:GROUP BY は COUNT(DISTINCT) に比べて処理速度が向上する可能性がある。- データのグループ化と集計を同時に行いたい場合には有効。
7. COUNT(DISTINCT)のよくあるエラーと解決策
COUNT(DISTINCT) を使用する際に、いくつかのよくあるエラーが発生することがあります。
ここでは、代表的なエラーとその解決策を紹介します。7.1 エラー1: COUNT(DISTINCT column1, column2) が使えない
エラーの原因
MySQLでは、複数カラムを対象にしたCOUNT(DISTINCT column1, column2)がサポートされていません。
直接この構文を使用するとエラーになります。解決策: CONCAT() を使用する
複数カラムを結合し、それをCOUNT(DISTINCT)に適用することでエラーを回避できます。SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;
💡 ポイント:CONCAT(column1, '-', column2) を使うことで、複数カラムのユニークデータを作成可能。COUNT(DISTINCT CONCAT(...)) で組み合わせごとのユニーク値を取得できる。
7.2 エラー2: NULL値が含まれている場合、期待通りに動作しない
エラーの原因
COUNT(DISTINCT column_name) は NULL値を無視 するため、NULLを含むカラムで期待通りの結果が得られないことがあります。
解決策: IFNULL() を使用する
NULLを別のデフォルト値(例: '' または 'unknown')に置き換えることで、正しくカウントできます。SELECT COUNT(DISTINCT IFNULL(email, 'unknown')) FROM users;
💡 ポイント:IFNULL(column_name, 'default_value') を使用することで、NULL値を適切に処理できる。
7.3 エラー3: COUNT(DISTINCT)が遅い
エラーの原因
COUNT(DISTINCT) は、すべてのデータをスキャンするため、大規模なデータセットでは処理が遅くなる可能性があります。
解決策: インデックスを活用する
ALTER TABLE users ADD INDEX (country);
💡 ポイント:- インデックスを設定すると、検索速度が向上する可能性がある。
EXPLAIN を使ってクエリの最適化状況を確認すると良い。
EXPLAIN SELECT COUNT(DISTINCT country) FROM users;
これらの対策を活用すれば、COUNT(DISTINCT) の実用性を向上させ、パフォーマンスの問題を回避することができます。
8. よくある質問(FAQ)
ここでは、COUNT(DISTINCT)に関するよくある質問をまとめました。8.1 COUNT(*)とCOUNT(DISTINCT column_name)の違いは?
違いのポイント
| 関数 | 説明 |
|---|
COUNT(*) | 全レコードの数をカウント(NULL含む) |
COUNT(DISTINCT column_name) | ユニークな値の数をカウント(NULL除外) |
使用例
SELECT COUNT(*) FROM users;
SELECT COUNT(DISTINCT email) FROM users;
💡 ポイント:COUNT(*) は すべてのレコードをカウント。COUNT(DISTINCT column_name) は ユニークな値の数を取得(NULLは除外)。
8.2 DISTINCTとGROUP BYの違いは?
| 機能 | DISTINCT | GROUP BY |
|---|
| 目的 | ユニークな値を取得 | グループごとの集計を行う |
| 使い方 | SELECT DISTINCT column_name | SELECT column_name, COUNT(*) GROUP BY column_name |
| 例 | ユニークな国を取得 | 各国のユーザー数をカウント |
使用例
-- DISTINCTを使う
SELECT DISTINCT country FROM users;
-- GROUP BYを使う
SELECT country, COUNT(*) FROM users GROUP BY country;
💡 ポイント:DISTINCT は 単純に重複データを除外。GROUP BY は データをグループ化し、集計関数と組み合わせることが可能。
8.3 COUNT(DISTINCT)は遅い?
問題点
COUNT(DISTINCT) は すべてのデータをスキャンするため、データ量が多いと処理が遅くなる可能性がある。
解決策: インデックスを活用する
ALTER TABLE users ADD INDEX (country);
代替手法: GROUP BY を活用する
SELECT country, COUNT(*) FROM users GROUP BY country;
💡 ポイント:- インデックスを適用すると検索速度が向上する可能性がある。
GROUP BY を活用すると、COUNT(DISTINCT) より高速な結果が得られる場合がある。
8.4 COUNT(DISTINCT column1, column2)を使う方法は?
問題点
- MySQLでは
COUNT(DISTINCT column1, column2) はサポートされていない。
解決策: CONCAT() を使用する
SELECT COUNT(DISTINCT CONCAT(country, '-', city)) FROM users;
💡 ポイント:CONCAT(column1, '-', column2) を使うことで、複数カラムのユニークデータを作成可能。COUNT(DISTINCT CONCAT(...)) で組み合わせごとのユニーク値を取得できる。
これらの質問を参考にすることで、COUNT(DISTINCT) をより効率的に活用することができます。
9. まとめ
本記事では、MySQLのCOUNT(DISTINCT)の使い方について詳しく解説しました。
最後に、この記事のポイントを振り返ります。9.1 この記事で学んだこと
✅ MySQLでデータの件数を取得する方法COUNT(*) は全レコードの数を取得COUNT(column_name) はNULLを除外したカウントCOUNT(DISTINCT column_name) でユニークなデータの件数を取得
✅ DISTINCTとCOUNT(DISTINCT)の違いDISTINCT は重複を除いたデータを取得COUNT(DISTINCT column_name) はユニークな値の数をカウント
✅ 複数カラムのCOUNT(DISTINCT)の使い方- MySQLでは
COUNT(DISTINCT column1, column2) が直接使えないため、CONCAT() を利用する
✅ パフォーマンスの最適化方法- インデックスを適用 することで、検索速度を向上させる
GROUP BY + COUNT を使用することで、高速なクエリが可能
9.2 この記事を活用してできること
この知識を活用すれば、以下のようなデータ集計が可能になります。
🔹 ユニークなユーザー数の集計 🔹 特定の条件に応じたデータの件数取得 🔹 複数カラムを組み合わせたユニークデータのカウント 🔹 大規模データセットでのクエリの最適化 今後、MySQLでデータの集計や最適化を行う際は、ぜひこの記事を参考にしてみてください!