← Debugging Guides

阅读中文版本

MySQL ERROR 1055 — ONLY_FULL_GROUP_BY Rejects the Query

Fix MySQL 1055 by grouping or aggregating every non-aggregated selected column, and avoid disabling ONLY_FULL_GROUP_BY to hide invalid SQL.

intermediatedebuggingmysqlsqlgroup-by

Symptoms

  • ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause
  • The query ran on an old MySQL and fails after upgrading to 5.7+/8.0
  • Adding a column to the SELECT list suddenly errors

Possible causes

  • A selected column is neither aggregated nor listed in GROUP BY
  • The intent was one representative row per group but ONLY_FULL_GROUP_BY is enabled
  • The query relies on MySQL-specific lax grouping that is now disallowed

Diagnosis steps

Read the offending expression number

mysql -e "SELECT id, COUNT(*) FROM orders GROUP BY status"

Interpretation

The error names the position of the non-grouped column; add it to GROUP BY or aggregate it.

Check the SQL mode

mysql -e "SELECT @@sql_mode"

Interpretation

ONLY_FULL_GROUP_BY being present explains why the lax query is rejected.

Root cause

With ONLY_FULL_GROUP_BY enabled (default in MySQL 5.7+ and 8.0), every column in the SELECT list must be functionally dependent on the GROUP BY columns or wrapped in an aggregate. This prevents nondeterministic rows.

Fix

Add the column to GROUP BY, wrap it in an aggregate such as MIN/MAX/ANY_VALUE when a specific value is acceptable, or rewrite using a window function or a join to select one row per group.

Risk note

Disabling ONLY_FULL_GROUP_BY makes results nondeterministic across servers and versions; do not disable it to silence errors.

Verify the fix

Run the rewritten query and confirm it returns one deterministic row per group; verify @@sql_mode still includes ONLY_FULL_GROUP_BY.

Symptoms

This debugging guide addresses “MySQL ERROR 1055 — ONLY_FULL_GROUP_BY Rejects the Query”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause
  • The query ran on an old MySQL and fails after upgrading to 5.7+/8.0
  • Adding a column to the SELECT list suddenly errors

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Read the offending expression number

mysql -e "SELECT id, COUNT(*) FROM orders GROUP BY status"

The error names the position of the non-grouped column; add it to GROUP BY or aggregate it.

Step 2: Check the SQL mode

mysql -e "SELECT @@sql_mode"

ONLY_FULL_GROUP_BY being present explains why the lax query is rejected.

Likely contributors, in order of frequency:

  • A selected column is neither aggregated nor listed in GROUP BY
  • The intent was one representative row per group but ONLY_FULL_GROUP_BY is enabled
  • The query relies on MySQL-specific lax grouping that is now disallowed

Root Cause

With ONLY_FULL_GROUP_BY enabled (default in MySQL 5.7+ and 8.0), every column in the SELECT list must be functionally dependent on the GROUP BY columns or wrapped in an aggregate. This prevents nondeterministic rows.

The Fix

Add the column to GROUP BY, wrap it in an aggregate such as MIN/MAX/ANY_VALUE when a specific value is acceptable, or rewrite using a window function or a join to select one row per group.

Watch out: Disabling ONLY_FULL_GROUP_BY makes results nondeterministic across servers and versions; do not disable it to silence errors.

-- ❌ id not grouped nor aggregated (ERROR 1055)
-- SELECT status, id FROM orders GROUP BY status;

-- ✅ aggregate a representative value
SELECT status, MIN(id) AS first_id, COUNT(*) AS n
FROM orders
GROUP BY status;

-- ✅ or group all selected columns
SELECT status, id, COUNT(*) FROM orders GROUP BY status, id;

Verify and Prevent

Run the rewritten query and confirm it returns one deterministic row per group; verify @@sql_mode still includes ONLY_FULL_GROUP_BY.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.