Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLのwhere句でcount関数を条件に使うことはできるのでしょうか?

SQLのwhere句でcountを使う

emp_no(社員番号)をカウントして3万人以上の社員がいる部署を部署テーブル(departments)と社員・部署紐付けテーブル(dept_emp)から抽出しようとしたところ、where句でcountを使うと、syntaxエラーとなりました。

以下はMySQLでの実行例です。一回目のSQLはwhere句なしで、すべての部署の社員数を抽出しています。二回目のSQLでwhere句にcount関数を使った部分がエラーとなっています。

SELECT dept_name, count(emp_no) FROM `dept_emp`
left join departments on dept_emp.dept_no = departments.dept_no
group by dept_emp.dept_no;

+--------------------+---------------+
| dept_name          | count(emp_no) |
+--------------------+---------------+
| Marketing          |         20211 |
| Finance            |         17346 |
| Human Resources    |         17786 |
| Production         |         73485 |
| Development        |         85707 |
| Quality Management |         20117 |
| Sales              |         52245 |
| Research           |         21126 |
| Customer Service   |         23580 |
+--------------------+---------------+
9 rows in set (0.12 sec)

SELECT dept_name, count(emp_no) FROM `dept_emp`
left join departments on dept_emp.dept_no = departments.dept_no
group by dept_emp.dept_no
where count(emp_no) > 30000;

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where count(emp_no) > 30000' at line 2

実は、countなどの集計関数を単純にwhereで扱うことは出来ないんですね。絞り込み条件にcountを組み込みたい場合は、havingを使います。

参考)count関数の値をwhere句で使用する方法について| OKWAVE

以下のようにhavingを使って記述すると、社員3万人以上の部署名(dept_name)一覧が抽出できました。

SELECT dept_name, count(emp_no) FROM `dept_emp`
left join departments on dept_emp.dept_no = departments.dept_no
group by dept_emp.dept_no
having count(emp_no) > 30000;

+-------------+---------------+
| dept_name   | count(emp_no) |
+-------------+---------------+
| Production  |         73485 |
| Development |         85707 |
| Sales       |         52245 |
+-------------+---------------+
3 rows in set (0.79 sec)

count関数の引数内に3値論理式で条件を指定する方法

havingを使う以外に、count関数の引数内に条件を記述することも可能です。3値論理式は、真と偽の他に第三の「不明」という値を取ります。

参考)3値論理とNULL (1/3):CodeZine(コードジン)

3値論理式は直感的に理解しづらいのですが、目的の動作をさせるために非常に短いコードで記述が可能です。

以下のようにcount関数の引数に条件を記述すると、全社員のうち、性別が男性(gender=’M’)の数をカウントできます。

mysql> select count(gender='M' or null) from employees;
+---------------------------+
| count(gender='M' or null) |
+---------------------------+
|                    179973 |
+---------------------------+
1 row in set (0.08 sec)

【関連記事】
SQL countの条件は引数内に記述できる 単クエリで複数の件数を取得する方法 

employees(社員テーブル)にはこのようなデータが入っています。group byでgender(性別)を指定すると、それぞれの性別のカウントが取得できます。

mysql> select * from employees limit 10;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10003 | 1959-12-03 | Parto      | Bamford   | M      | 1986-08-28 |
|  10004 | 1954-05-01 | Chirstian  | Koblick   | M      | 1986-12-01 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |
|  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10007 | 1957-05-23 | Tzvetan    | Zielinski | F      | 1989-02-10 |
|  10008 | 1958-02-19 | Saniya     | Kalloufi  | M      | 1994-09-15 |
|  10009 | 1952-04-19 | Sumant     | Peac      | F      | 1985-02-18 |
|  10010 | 1963-06-01 | Duangkaew  | Piveteau  | F      | 1989-08-24 |
+--------+------------+------------+-----------+--------+------------+
10 rows in set (0.00 sec)

mysql> select count(*), gender from employees group by gender;
+----------+--------+
| count(*) | gender |
+----------+--------+
|   179974 | M      |
|   120051 | F      |
+----------+--------+
2 rows in set (0.17 sec)

直感的には、count(gender=’M’)を指定すれば目的の値が抽出できそうですが、結果はこうなります。

mysql> select count(gender='M') from employees;
+-------------------+
| count(gender='M') |
+-------------------+
|            300025 |
+-------------------+
1 row in set (0.04 sec)

gender=’M’と指定しているのに、count(*)と同じ値が返ってきてしまうんですね。エラーも出ませんし、一見正しく見えてしまうので開発現場ではバグ発生の原因になることも考えられます。

多くの人がコードをメンテナンスするようなケースで3値論理式を使用する際には、コメントを付与するなど、工夫するのが良いでしょう。

SQLのwhere句でcountを使う方法のまとめ

ポテパンダの一言メモ
  • SQLのwhereで単純にcount関数を使うとsyntaxエラーになる
  • 絞り込み条件にcountを使いたい場合はhavingを利用する
  • countの引数に3値論理式を使うことで、カウント対象の条件を指定可能

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。