支援対象地域:札幌、仙台、関東、愛知、関西、広島、福岡


はじめに

SQLを学習したての時に一度はつまづくであろうWHERE句とHAVING句。どちらも行を絞り込むという意味では同じですがなぜ同じような機能を持った句がSQLには備わっているのか、WHERE句とHAVING句の説明も交えながらその違いを簡単に説明しようと思います。

WHERE句の基本

まず初めにWHERE句とは、WHEREキーワードから始まる一連の記述の事を言います。WHERE句を用いることによって処理対象となる行の絞り込みができます。このWHERE句を自在に使えない事には、データの管理を自在に操作することは出来ません。

WHERE句が使用可能な文はSELECT, UPDATE, DELETE文です。INSERT文では使えないので注意しましょう。WHERE句を利用するにはWHEREの後ろに式を記述します。ただしWHEREの後ろにはどんな式でも書けるわけではありません。書けるのは式の結果がtrueかfalseになる条件式のみです。

たとえば[値段 < 3000]という式は、データベース上に管理されている「値段」という列の値が3000未満の場合はtrueが、3000以上の場合はfalseと判定されるので、WHERE句の条件式として使用できます。しかし[値段 + 1000]という式の答えはtrueともfalseともならないので、WHERE句の式としては使用する事ができません。

実際にデータベースを利用してどのような結果になるのかを見てみましょう。下図の商品テーブルを利用します。(H2DBを使用しております。)

商品テーブル

商品ID 商品名 値段
1 お菓子 100
2 洗剤 300
3 牛肉 500

このテーブルに対して

SELECT 商品ID, 商品名, 値段 (=SELECT*)
FROM 商品;

とするとこのように商品テーブルの全ての内容が表示されますが

WHERE句を用いて

SELECT 商品ID, 商品名, 値段 (=SELECT*)
FROM 商品
WHERE 商品ID = 1;

とすることでWHERE句の後ろに記述されている商品ID=1に該当する行に絞り込まれ、このように表示されます。

このようにWHERE句を使う事によって行の絞り込みを行い、目的のデータを引き出すことが可能になります。ただしWHERE句にはSUM, AVG, COUNT等の集計関数を用いることができません。その理由も含め「HAVING句とWHERE句の違い」を説明します。

HAVING句とWHERE句の違い

ではHAVING句とはどのようなものなのでしょうか?HAVING句もWHERE句と同様、行の絞り込みをする際に使われるものですが絞り込みを実行するタイミングに違いがあります。

WHERE句はまず初めに行の絞り込みを行い、その次にグループ化、そして集計・列選択を行います。

一方HAVING句は、上記の行程が終わり集計結果がすべてそろった最後の段階で絞り込みが行われます。そのため、集計関数を記述することが可能となるのです。また記述する場所も異なるので注意して見ましょう。

では実際に下図の家計簿テーブルを用いHAVING句を試してみます。

家計簿テーブル

カテゴリ 支出 収入
食費 2000 0
食費 1000 0
交通費 500 0
交通費 300 0
給料 0 300000

このテーブルを基にカテゴリ毎の支出の集計表を表示したいと思います。

HAVING句無しで行うと

SELECT カテゴリ, SUM(支出) AS カテゴリ別支出の合計
FROM 家計簿
GROUP BY カテゴリ;

このように支出が発生しない「給料」も表示されてしまいます。

ではWHERE句を使用した場合どのようになるのでしょうか?

SELECT カテゴリ, SUM(支出) AS カテゴリ別支出の合計
FROM 家計簿
WHERE SUM(支出) > 0
GROUP BY カテゴリ;

このSQL文を実行するとエラーが発生してしまいます。なぜならWHERE句を処理する段階では、まだ集計が終わってないからです。

ではHAVING句を使用してカテゴリ毎の支出の合計を表示してみましょう。

SELECT カテゴリ, SUM(支出) AS カテゴリ別支出の合計
FROM 家計簿
GROUP BY カテゴリ
HAVING SUM(支出) > 0;

このSQLを実行するとカテゴリ毎の支出の合計を表示することができます。

このようにWHERE句とHAVING句には大きな違いがあるのです。

まとめ

上記で説明した通り、WHERE句とHAVING句の大きく異なる点は、処理内容を絞り込むタイミングが異なるという点です。WHERE句は最初に行を絞り込むのに対し、HAVING句はWHERE句による検索⇒GROUP BYによるグループ化⇒集計関数による集計と、列選択が終わったあとに絞り込みを行います。そのため、WHERE句には集計関数は利用できませんが、HAVING句には集計関数を用いることができます。
今回説明した内容はWHERE句とHAVING句の違いだけを記述したものです。上記で説明したWHERE句、HAVING句の使い方以外にもたくさん使い方があるので、ぜひ調べてSQLを使いこなしましょう!