【データベース】SQLクエリ – WHERE句とHAVING句との違い

今回はデータベースに関してSQLクエリにおける、WHERE句とHAVING句の違いについて解説いたします。

データベースを初めて触るようなプログラミング初心者の方は同じような動きをするWHERE句とHAVING句の存在に疑問を持つかと思います。

一見同じような動きに見えてできることが全然違いますので、その違いをしっかりと抑えて自分が求める結果を導くクエリをかけるようにしましょう。

HAVING句とWHERE句はやること自体は酷似していますので、そのあたりで上手く使い分けできず困っているという方や、両方学んだけど何が違うのかわかんないといった疑問など、そのような問題の解消になるようにお手伝いできればなと思います。

ポイント

WHERE句とHAVING句の違いは文を書く位置
・クエリが実行されるタイミングが重要

スポンサーリンク
目次

WHERE句とHAVING句のそれぞれの動き

それでは初めにWHERE句とHAVING句のそれぞれの動きに関して解説いたします。

手っ取り早く違いだけ知りたいという方はこちらへスキップ!

WHERE句

最も一般的なクエリの一つである「WHERE」について解説いたします。

WHEREは以下のような構文で成り立つクエリです。

SELECT <カラム名> FROM <テーブル名>
WHERE <カラム名> = <値>


例 :
SELECT COLUMN1 , COLUMN2 , COLUMN3
FROM TABLE1
WHERE COLUMN1 = ‘DATA1’
;

FROM句で指定したテーブルが持っているカラムに対して、条件を設定し条件に合致するデータのみ行単位でデータをとってくる動きをします。

簡単に言えば、データのフィルタ機能ですね。
Webアプリの検索画面なんかでは絶対必要になるクエリです。

HAVING句

次に「HAVING」についてです。
WHERE句と殆ど同じ動きをするため、存在自体を忘れてしまっている人も多々いるかと思われるこのクエリですが、実はかなり有用性が高いものになっているので、無駄なクエリを書かないためにもしっかりと覚えておきたいです。

SELECT <カラム名> FROM <テーブル名>
GROUP BY <カラム名> HAVING <カラム名> = <値>


例 :
SELECT COLUMN1 FROM TABLE1
GROUP BY COLUMN1 HAVING COUNT(COLUMN1) > 3

こちらも、テーブルの何らかの形でとってきたカラムに対して、条件を設定し、その条件に合致する(持っている=HAVING)データをとってくるというものです。

話を聞くだけでは違いがさっぱり分からないと思いますが、HAVING句のポイントはGroup By の後ろにクエリが来ていることです。

これによりWHERE句にはできないことがHAVING句で出来るようになります。

WHERE句とHAVING句の違い

WHERE句とHAVING句の違いは簡単に実行されるタイミングが異なります。

タイミング自体は以下のように実行されます。

上記を見てもらえればわかると思いますが、WHEREの方が先に実行され、HAVINGが後に実行されます。
そして重要なのが、HAVING句はGROUP BYやSUMなどの集計関数よりも後に実行されるという点です。

これにより、GROUP BYなどで集計したデータに対して条件を設定することができます。
WHERE句では先に実行されるため、FROM句にサブクエリを用いたりしないと集計したデータに対する条件設定ができません。
サブクエリで無理やり実現したとしてもクエリの長文化にもつながり、可読性も著しく低下してしまいます。
何より面倒くさいです。

これがWHERE句とHAVINGの明確な違いであり、どちらを使用するかは集計したデータに対して条件を設定するか否かになります。

HAVINGの活用事例

それでは最後にHAVINGの活用場面についてご紹介いたします。

WHEREについては説明せずともわかると思のでHAVINGを使いたくなる場面というのをイメージしやすいように活用例をご紹介します。

1.合計値が一定数を超えるデータ群を見つける

例えば店舗ごとの売り上げが目標値に届いている店舗を見つけたいという時があったとします。
実際のテーブルは以下のようなものでした。

T_SALES

店舗名商品名売り上げ金額
商店A商品A10,000,000
商店A商品B2,600,000
商店A商品C7,500,000
商店B商品A11,400,000
商店B商品B4,300,000
商店B商品C6,800,000
商店C商品A7,000,000
商店C商品B3,400,000
商店C商品C8,000,000

上記のようなデータにおいて売上総額が20,000,000を超える店舗はどこなのか?ということを知りたいときにHAVINGは役に立ちます。

まずは、データは商品ごと、店舗ごとに分かれてしまっていますが、ほしいのは店舗ごとの総売上数なので
店舗をキーにグループ化してあげます。

GROUP BY 店舗名

次に総売上金額が2000万を超えるデータが欲しいので、以下のような条件を設定します。

SUM(売上) > 20,000,000


ここにはSUMという集計関数が含まれているので、WHERE句では使えず、HAVING句で使用することになります。
すると最終的なクエリは以下のようになります。

SELECT
店舗名
FROM
T_SALES
GROUP BY
店舗名
HAVING
SUM(売上) > 20000000

結果としては売り上げが2000万を超える店舗は商店Aと商店Bになるはずなので、
商店A、商店Bという結果が得られます。

2. データの出現回数が一定値を超えるデータを取得する

次はグループ化したデータ群においてデータの出現回数が一定値を超えるデータを取得してみようと思います。

例えば次のよう顧客の来店データがあった場合に、10月において来店回数が3回以上の顧客の情報を取得したいとします。

T_CUSTOMER

店舗名顧客名来店日購入金額
商店A田中五郎202210085,000
商店A鈴木次郎2022100912,000
商店A斎藤山田曽2022101020,000
商店A田中五郎202210158,000
商店A佐藤武2022101510,000
商店A高嶺花子2022101650,000
商店A鈴木次郎2022102210,000
商店A田中五郎2022103011,000
商店A佐藤武202211038,000
商店A鈴木次郎202211054,000

上記のデータの場合、まず10月のみという条件を指定したいので、WHERE句に以下のように指定します。
(BETWEENは [対象の要素] BETWEEN [最小値] AND [最大値] で指定できます。)

WHERE 来店日 BETWEEN 20221001 AND 20221031

さらに顧客ごとの来店回数が欲しいので、GROUPBYには顧客名を入れます。

GROUP BY 顧客名

そして肝心のHAVING句ですが、3回以上データがあるものを取得したいのでCOUNT関数を使い以下のように指定できます。

HAVING COUNT(*) >= 3

以上の内容を統合して最終的に以下のようなクエリになります。

SELECT
顧客名
FROM
T_CUSTOMER
WHERE
来店日 BETWEEN 20221001 AND 20221031
GROUP BY
顧客名
HAVING
COUNT(*) >= 3

上記のクエリの結果としては10月に来店している回数が3回以上の顧客は田中五郎さんだけですので、結果として田中五郎さんが得られるはずです。

上記のようにHAVING句の使用感覚としてはGROUP BYしたデータ群に対して何らかの条件を設定したい時に活躍します。

いかがでしたでしょうか。
HAVING句は使えるようになるとかなり便利だと感じることが多いと思いますので、
WHERE句としっかりと使い分けできるようにしたいですね。

今回はここまでです。

お疲れ様でした。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

本業ではPHPを使ったWEBアプリやJavaを使用した基幹アプリを作成しております。Pythonは個人的に勉強しており、E資格を取ったりしたおかげで、業務でAIの研究とかも任されるようになりました。学習のアウトプットのために本サイトを運営しておりますが、これからPythonを学ぶという人のお役に立てればいいなと思います。わからないことや調査して記事にしてほしいことがございましたらご連絡いただけると幸いです。

コメント

コメントする

目次
閉じる