SQLで利用するHAVING句について構文ルールと使い方、注意点などをわかりやすく解説します。
参考 SELECT文
HAVING句を利用するとGROUP BY句によってグループ化されたレコードに対して取得条件を指定することできます。
このページではHAVING句の使い方/構文ルールを初心者向けに解説します。
プログラマーやシステムエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識です。是非最後までご覧ください。
SELECT文の基本から復習しておきたい!という方は以下の記事から学習しておきましょう。
HAVING句の使い方・構文ルール
SELECT (カラム名),(カラム名), ・・・・ FROM (テーブル名) WHERE (レコード取得条件) GROUP BY (カラム名),(カラム名), ・・・・ HAVING (グループの値に対する条件);
HAVING句はGROUP BY句の後ろに記述します。
早速以下のようなテーブルに対してHAVING句を利用したSQL文を見てみましょう。
SELECT FM, SUM(Japanese) FROM PointList GROUP BY FM HAVING SUM(Japanese) = 180; /* 実行結果 +----------+-----------+ | FM | SUM | +----------+-----------+ | 男 | 180 | +----------+-----------+ */
HAVING句では「SUM(Japanese) = 180」と指定しているため、結果は1行だけになります。
仮にHAVING句を利用せずに同じようなSQL文を実行すると以下のように、すべての結果が表示されます。
SELECT FM, SUM(Japanese) FROM PointList GROUP BY FM; /* 実行結果 +----------+-----------+ | FM | SUM | +----------+-----------+ | 男 | 180 |←先ほどのサンプルコードではこちらの行だけが表示されていた | 女 | 320 | | NULL | 110 | +----------+-----------+ */
関連 【SQL】SUM関数(SELECT SUM)を1分でわかりやすく解説
HAVING句の注意点
HAVING句の基本は以上。一度わかってしまえば決して難しくはありません。
ここからはHAVING句を利用したいくつかのサンプルコードを見ながら、HAVING句に関する細かなTipsや注意点について解説します。
HAVING句:AS句との併用
HAVING句ではAS句で付与された別名を条件式の中で利用することができます。
SELECT FM, SUM(Japanese) AS Summary FROM PointList GROUP BY FM HAVING Summary >= 300; /* 実行結果 +----------+-----------+ | FM | SUM | +----------+-----------+ | 女 | 320 | +----------+-----------+ */
4行目のHAVING句では、1行目のAS句で付与された「Summary」という別名が用いられていることが確認できます。
COUNT関数を組み合わせて実行したSQL文がこちら。
SELECT FM, COUNT(Japanese) AS Count FROM PointList GROUP BY FM HAVING Count > 2 ; /* 実行結果 +----------+-----------+ | FM | COUNT | +----------+-----------+ | 男 | 3 | | 女 | 5 | +----------+-----------+ */
HAVING句:WHERE句との併用
続いてHAVING句とWHERE句を同時に記述した場合です。
HAVING句とWHERE句を同時に利用する場合は、①WHERE句で指定した条件を満たすデータの抽出&グループ化 ⇒②HAVING句で指定したグループ化されたデータに対する条件の適用 の順番で処理が行われます。
SELECT FM, COUNT(Japanese) AS Count50 FROM PointList WHERE Japanese >= 50 GROUP BY FM HAVING Count50 > 0; /* 実行結果 +----------+-----------+ | FM | COUNT | +----------+-----------+ | 男 | 2 | | 女 | 3 | +----------+-----------+ */
つまり、WHERE句ではJapanaeseカラムが「50以上」という条件を指定しているので上記の黄色ハイライト部分が抜き出され、その後でグループ化が行われるということです。
HAVING句の条件を変えた結果も併せてみてみると理解が深まるかもしれません。↓
SELECT FM, COUNT(Japanese) AS Count50 FROM PointList WHERE Japanese >= 50 GROUP BY FM HAVING Count50 > 2; /* 実行結果 +----------+-----------+ | FM | COUNT | +----------+-----------+ | 女 | 3 | +----------+-----------+ */
最後にHAVING句を利用した実践的なサンプルコードを記載しておきます。以下のSQL文の内容を理解できればこのページで解説した内容の理解はOKです!
-- テーブルの作成/レコード投入 CREATE TABLE sales_data ( id INT PRIMARY KEY, product CHAR(1), sales_date DATE, sales_amount INT ); INSERT INTO sales_data (id, product, sales_date, sales_amount) VALUES (1, 'A', '2023-04-01', 100), (2, 'B', '2023-04-01', 200), (3, 'A', '2023-04-02', 150), (4, 'C', '2023-04-02', 300), (5, 'B', '2023-04-03', 250), (6, 'A', '2023-04-03', 120), (7, 'C', '2023-04-03', 350); -- 各商品ごとの合計売上金額が450以上のものを抽出 SELECT product, SUM(sales_amount) AS total_sales_amount FROM sales_data GROUP BY product HAVING total_sales_amount >= 450; /* 結果 | product | total_sales_amount | |---------|--------------------| | B | 450 | | C | 650 | |---------|--------------------| */ -- 2023年4月2日以降のデータを対象に各商品ごとの合計売上金額が300以上のものを抽出するクエリ SELECT product, SUM(sales_amount) AS total_sales_amount FROM sales_data WHERE sales_date >= '2023-04-02' GROUP BY product HAVING total_sales_amount >= 300; /* 結果 | product | total_sales_amount | |---------|--------------------| | C | 750 | |---------|--------------------|
SQLを1から学習したい方は
SQLやデータベースの仕組みを1から学習したい方(学び直したい方)向けに、現役エンジニア達のスキルを結集して 完全無料 のSQL教材を作成しました。
SQLは決して難しい技術ではないので、エンジニアであれば「当たり前のように」扱えて当然かも・・・?
とはいえ、案外SQLをちゃんと使ったことがない人も多いはずです。この機会に是非一度ご覧になってみてください。
システムエンジニアを目指したい方は
システムエンジニアを目指す方や、IT知識を1から身につけたい方は以下のページをご覧ください。
正直どこから学び始めればよいかわからない。どのように勉強していけば、エンジニアとしてのスキルが磨けるか?が分からない・・・という方は必見です。
システムエンジニア向けに「できるエンジニア」になる方法を1から解説しておりますので、是非ご覧ください。