MySQL 5.7.5 以降で発生するエラー "only_full_group_by" の原因と解決方法

2024-04-02

MySQL でクエリを実行時に発生する only_full_group_by 関連エラーについて

MySQL 5.7.5 以降では、only_full_group_by という新しい SQL モードがデフォルトで有効になっています。このモードは、GROUP BY 句で選択されていない列を関数で集計する場合に、エラーが発生するようになります。

エラーメッセージ例

ERROR 1055 (HY000): 'only_full_group_by' フラグが有効なため、GROUP BY 句で選択されていない列 'country_code' を関数 'COUNT()' で使用できません。

原因

このエラーが発生するのは、GROUP BY 句で選択されていない列を関数で集計しようとしているためです。only_full_group_by モードが有効な場合、集計対象となるすべての列を GROUP BY 句で選択する必要があります。

解決策

このエラーを解決するには、以下のいずれかの方法を試してください。

  1. GROUP BY 句で集計対象となるすべての列を選択する
SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code;
  1. only_full_group_by モードを無効にする
SET SQL_MODE = 'NO_ONLY_FULL_GROUP_BY';

SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code;
  1. 集計関数に GROUP BY オプションを使用する
SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code WITH ROLLUP;

詳細

only_full_group_by モードについて詳しくは、以下のドキュメントを参照してください。

補足

  • only_full_group_by モードは、MySQL 5.7.5 以降でデフォルトで有効になっています。
  • このモードを無効にすることはできますが、セキュリティ上のリスクがあるため、推奨されません。
  • GROUP BY 句で選択されていない列を関数で集計する必要がある場合は、上記の解決策を参考にしてください。
  • 上記以外にも、エラーが発生する原因はいくつか考えられます。詳細な情報は、エラーメッセージの内容や、使用している MySQL のバージョンなどを考慮する必要があります。
  • 問題解決に困難を感じている場合は、専門家に相談することをおすすめします。



例1: エラーが発生する例

SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code;

このコードを実行すると、以下のエラーが発生します。

ERROR 1055 (HY000): 'only_full_group_by' フラグが有効なため、GROUP BY 句で選択されていない列 'country_code' を関数 'COUNT()' で使用できません。
SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code,
  country_name;

このコードでは、country_codecountry_name の両方を GROUP BY 句で選択しているので、エラーは発生しません。

SET SQL_MODE = 'NO_ONLY_FULL_GROUP_BY';

SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code;

このコードでは、SET SQL_MODE ステートメントを使用して、only_full_group_by モードを無効にしています。

SELECT
  country_code,
  COUNT(*) AS total_count
FROM
  customers
GROUP BY
  country_code WITH ROLLUP;

このコードでは、COUNT(*) 関数に GROUP BY オプションを使用しています。このオプションを使用すると、GROUP BY 句で選択されていない列も含めて集計することができます。




only_full_group_by エラーに対処するその他の方法

CASE 式を使用する

GROUP BY 句で選択されていない列を条件として使用したい場合は、CASE 式を使用することができます。

SELECT
  country_code,
  COUNT(CASE WHEN country_name = 'Japan' THEN 1 END) AS total_count_japan
FROM
  customers
GROUP BY
  country_code;

このコードでは、country_name 列が 'Japan' かどうかを条件として、COUNT() 関数を使用して集計しています。

サブクエリを使用する

SELECT
  country_code,
  (SELECT COUNT(*) FROM customers WHERE country_code = c.country_code) AS total_count
FROM
  customers AS c
GROUP BY
  c.country_code;

このコードでは、サブクエリを使用して、country_code ごとの顧客数を集計しています。

集計結果を後から結合する

GROUP BY 句で選択されていない列を関数で集計したい場合は、まず GROUP BY 句で必要な列を絞り込み、その後別のクエリで集計結果を結合することができます。

-- 1. GROUP BY で必要な列を絞り込む
SELECT
  country_code
FROM
  customers
GROUP BY
  country_code;

-- 2. 集計結果を結合する
SELECT
  c.country_code,
  COUNT(*) AS total_count
FROM
  (
    SELECT
      country_code
    FROM
      customers
    GROUP BY
      country_code
  ) AS c
LEFT JOIN
  (
    SELECT
      country_code,
      COUNT(*) AS total_count
    FROM
      customers
    GROUP BY
      country_code
  ) AS t
ON
  c.country_code = t.country_code;

このコードでは、まず 1 番目のクエリで country_code ごとのグループを作成し、2 番目のクエリで country_code ごとの顧客数を集計し、最後に結合しています。

  • シンプルな方法でエラーに対処したい場合は、GROUP BY 句で集計対象となるすべての列を選択するのがおすすめです。
  • より複雑な条件で集計を行いたい場合は、CASE 式やサブクエリを使用することができます。
  • パフォーマンスを考慮する場合は、集計結果を後から結合する方法が有効な場合があります。

mysql sql group-by


SQL Server、SQL Server、Oracleにおけるデータ型比較:VARCHAR(MAX) vs VARCHAR2 vs CLOB vs NCLOB vs BLOB

VARCHAR2は、Oracleで最も一般的な可変長文字列データ型です。VARCHAR(MAX)と同様に、最大2, 147, 483, 647文字までの文字列を格納できます。CLOBは、Oracleで非常に大きな文字列を格納するために使用されるデータ型です。最大4GBまでの文字列を格納できます。...


DECIMAL、NUMERIC、MONEY型?それぞれのメリットとデメリットを比較解説

DECIMAL型長所: 固定小数点精度で、小数点以下最大10桁まで正確に格納できます。 金融計算において最も精度が高く、誤差が発生しません。 多くのデータベースシステムで標準的にサポートされています。固定小数点精度で、小数点以下最大10桁まで正確に格納できます。...


MySQL/MariaDB で ID シーケンス断片化を修復: min と max 変数をリセットする方法

このような状況下で、新しいレコード挿入時に適切な ID 値が割り当てられるように、min と max 変数をリセットする必要があります。このチュートリアルでは、min と max 変数をリセットする方法を 2 つの方法で説明します。この方法は、以下の SQL ステートメントを使用して、min と max 変数をリセットします。...


データベース操作の悩みを解決!MySQL/MariaDBでグループとユーザーの所属関係を自由自在に

すべてのグループを選択するユーザーがグループに属しているかどうかを確認するこのチュートリアルでは、次の表を使用します。すべてのグループを選択するには、次のクエリを使用します。このクエリは、groups テーブルからすべての行を返します。各行には、group_id と group_name という 2 つのカラムが含まれます。...