MySQL GROUP BY 句と HAVING 句の例

⚡ スマートサマリー

SQLのGROUP BY句とHAVING句は、詳細な行を要約レポートに変換します。GROUP BY句は、同じ値を持つ行をグループごとに1行にまとめ、HAVING句は、COUNTなどの集計関数を適用した後に、それらのグループをフィルタリングします。

  • 📊 主な目的: GROUP BYは、同じ値を持つ行をグループ化し、グループ化された項目ごとに1行を返します。
  • 🧩 単一列グループping: グロウping 性別に関するメンバー表は、9行を2行に集約し、1行を女性用、もう1行を男性用としている。
  • 🔗 複数列グループping: グロウping 2 つの列の場合、どちらかの値が異なると行が一意であるとみなされるため、完全に一致する重複のみが統合されます。
  • 🧮 集約ペアリング: カウント、合計、 AVG、MIN、およびMAXは、グループごとに1つの値を計算し、それによって要約レポートが生成されます。
  • 🚦 持っていることと、どこにあるか: WHERE句はグループより前の行をフィルタリングしますping、その後HAVINGはグループをフィルタリングし、集計結果を受け入れるのはHAVINGのみです。
  • ⚠️ 厳格モードに関する注意: ONLY_FULL_GROUP_BY の場合、選択されたすべての列はグループ化されるか、集計関数で囲まれている必要があります。

SQL GROUP BY および HAVING 句

SQLのGROUP BY句とは何ですか?

GROUP BY 句は、次の目的で使用される SQL コマンドです。 同じ値を持つ行をグループ化するこれはSELECT文の中に記述され、通常は集計関数と組み合わせてデータベースから要約レポートを作成するために使用されます。

それがその機能です。 データを要約する データベースに格納されているデータ。GROUP BY句を含むクエリはグループ化クエリと呼ばれ、グループ化された項目ごとに1行を返します。

SQL GROUP BY 構文

句の目的が明確になったところで、基本的なグループ化クエリの構文を見てみましょう。

SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];

Pr_media

  • SELECT文…」は標準です SQL 選択 コマンドクエリ。
  • グループ化 列名1」はグループを実行する節ですping column_name1に基づきます。
  • [, column_name2, …]」はオプションであり、グループが他の列名である場合にそれを表します。ping 複数の列に対して実行されます。
  • [条件あり]」はオプションであり、GROUP BY句の影響を受ける行を制限するために使用されます。これは、 WHERE句ただし、グループが適用される場合を除きます。ping.

グロウping 単一列の使用

SQLのGROUP BY句の効果を最も簡単に確認する方法は、グループ化されていないクエリとグループ化されたクエリを比較することです。まずは、メンバーテーブル内のすべての性別エントリを返すシンプルなクエリから始めましょう。

SELECT `gender` FROM `members`;
性別
女性
女性
男性
女性
男性
男性
男性
男性
男性

9行が返され、すべての値が重複しています。性別ごとに一意の値を取得したいとします。以下のクエリは、GROUP BY句を追加します。

SELECT `gender` FROM `members` GROUP BY `gender`;

上記のスクリプトを実行すると、 MySQL ワークベンチ myflixdb に対して実行すると、次の結果が得られます。

性別
女性
男性

テーブルには性別が2種類しかないため、返された行は2行のみであることに注意してください。GROUP BY句は「男性」のメンバーをすべてグループ化して1行にまとめ、同様に「女性」のメンバーについても1行にまとめています。

グロウping 複数列の使用

グロウping 1つの列だけで集計するのは、実際のレポート作成には粗すぎる場合が多いです。GROUP BY句は、カンマで区切られた列のリストを受け付け、それらの値の組み合わせによって各グループを定義します。

映画のcategory_idの値と、それぞれの映画が公開された年の一覧を取得したいとします。まず、このシンプルなクエリの出力結果を見てみましょう。

SELECT `category_id`, `year_released` FROM `movies`;
カテゴリ ID リリース年
1 2011
2 2008
NULL 2008
NULL 2010
8 2007
6 2007
6 2007
8 2005
NULL 2012
7 1920
8 NULL
8 1920

強調表示された行は、結果に重複が含まれていることを示しています。同じクエリをGROUP BY句付きで実行すると、重複が削除されます。

SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;

上記のスクリプトを実行すると、 MySQL myflixdbに対するWorkbenchの実行結果は、以下に示すとおりです。

カテゴリ ID リリース年
NULL 2008
NULL 2010
NULL 2012
1 2011
2 2008
6 2007
7 1920
8 1920
8 2005
8 2007

GROUP BY句はcategory_idとyear_releasedの両方に対して動作し、 ユニーク 行。2007年のカテゴリ6の重複した2つの行は1つに統合されました。

経験則: カテゴリIDが同じでもリリース年が異なる場合、その行は一意のものとして扱われます。カテゴリIDとリリース年が複数の行で同じ場合、それらの行は重複とみなされ、そのうちの1つだけが表示されます。

グロウping および集計関数

重複を削除することは便利ですが、グループ化の真の力はping ペアになっているときに表示されます 集計関数集計関数は、各グループに対して 1 つの値を計算します。COUNT は行数をカウントし、SUM は値を加算し、 AVG、MIN、およびMAXはスプレッドを表します。

データベース内の男性会員と女性会員の総数を取得したいとします。以下のスクリプトはそれを実現します。

SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;

上記のスクリプトを実行すると、 MySQL myflixdb に対して Workbench を実行すると、以下の結果が得られます。

性別 COUNT(`membership_number`)
女性 3
男性 6

行は性別ごとにグループ化され、各グループ内の行数はCOUNT集計関数によってカウントされます。9つのメンバーレコードは2つの要約行に集約されます。

HAVING句を使用したクエリ結果の制限

グロウpingテーブルのすべての行に対して常に条件が必要なわけではありません。レポートを特定の条件に限定する必要がある場合もあり、そのためには HAVING 句を使用します。

映画のカテゴリIDが8のすべての公開年を知りたいとします。以下のスクリプトでその結果が得られます。

SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;

上記のスクリプトを実行すると、 MySQL myflixdbに対するWorkbenchの実行結果は、以下に示すとおりです。

映画ID タイトル ディレクター リリース年 カテゴリ ID
9 Honey moonERS ジョン・シュルツ 2005 8
5 ダディーズ・リトル・ガールズ NULL 2007 8

HAVING条件に該当するのは、カテゴリIDが8の映画のみです。

警告: MySQL 5.7以降では、デフォルトでONLY_FULL_GROUP_BYモードが有効になり、そのモードでは、movie_id、title、directorがグループ化も集計もされていないため、GROUP BY句を含むSELECT *は拒否されます。運用環境では、グループ化された列に明示的に名前を付けてください。例: SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;

WHERE、HAVING、GROUP BY、ORDER BY

初心者は、これら 4 つの節を混同しがちですが、これらはすべて結果セットを形成します。違いは を特定いたします。 MySQL それらを適用する際、WHERE は行がグループ化される前に実行され、HAVING はグループ化された後に実行され、ORDER BY は最後に実行されます。

何それがありません 実行時 集計関数を受け入れます
NeoCity グループの前に個々の行をフィルタリングしますping. GROUP BYの前に いいえ
グループ化 同じ値を持つ行をグループごとに1行にまとめます。 どこで 適用されない
HAVING GROUP BYによって生成されたグループをフィルタリングします。 GROUP BYの後 はい、例えば HAVING COUNT(*) > 2 の場合
ORDER BY 前の句を通過した行をソートします。 最後 はい、集約エイリアスはソート可能です。

実質的な影響はパフォーマンス上の問題です。WHERE句によるフィルタリングでは、グループより前の行が削除されます。ping 作業が開始されるため、集計結果に依存しない条件は、HAVING ではなく WHERE に含めるべきです。

よくあるご質問

はい。GROUP BY句は、一意の値ごとに1行を返すため、SELECT DISTINCT句とほぼ同じ方法で重複を削除します。集計関数は、各グループで計算された数値が必要な場合にのみ必要となります。

選択した列がGROUP BY句に含まれておらず、かつ集計関数で囲まれていない場合に、このエラーが発生します。 MySQL その列のどの値をグループに表示するかを決定できないため、クエリを拒否します。

COUNT(*) はグループ内のすべての行をカウントします。COUNT(column) はその列が存在しない行のみをカウントします。 NULLそのため、列に欠損値が含まれている場合は、2つの数値は異なる値になります。

はい。次のようなツール内のAIアシスタント MySQL ワークベンチ 「性別ごとのメンバー数」などのリクエストをグループ化されたクエリに変換します。グループをチェックします。ping 間違ったグループなので、自分でコラムを作成してくださいping もっともらしく見えるが、実際は間違っている合計値を算出する。

多くの場合、そうです。AI クエリ アシスタントは、次のような典型的な原因を検出します。 登録 グループの前に行を乗算しますpingあるいは、WHERE句ではなくHAVING句にフィルターを配置する。最終的な判断は、データを把握している人物に委ねられる。