ERROR 1241 (21000): Operand should contain 1 column(s) is raised when a subquery or row constructor used in a context that expects a single value returns more than one column. The error symbol is ER_OPERAND_COLUMNS.
Impact
The query is rejected immediately — no rows are read, written, or modified. This error is a parse-time/compile-time check, so it fires before any data access occurs. Any application that constructs subqueries dynamically (via ORMs such as SQLAlchemy, Hibernate, or ActiveRecord) will surface this as a database exception with the 1241 error code and SQLSTATE 21000. The transaction is not automatically rolled back, but the offending statement does not execute.
Common Causes
Scalar subquery returns multiple columns. A subquery in a
SELECTlist,WHEREclause, orSETassignment is expected to return a single column but selects two or more. For example:WHERE id = (SELECT id, name FROM users WHERE ...).IN subquery with a multi-column SELECT. Using
col IN (SELECT a, b FROM ...)—INwith a scalar left operand requires the subquery to return exactly one column.Row value comparison with mismatched column count. MySQL supports row constructors like
(a, b) = (SELECT x, y FROM ...), but if the subquery returns a different number of columns than the row constructor on the left side, this error fires.Accidental
SELECT *inside a scalar context. UsingSELECT *in a subquery when the table has more than one column, inside a context that requires a single value.ORM-generated subqueries. Query builders that programmatically add columns to subqueries can inadvertently expand a scalar subquery into a multi-column one.
Troubleshooting and Resolution Steps
Identify which subquery is at fault. Run the query manually in the MySQL CLI or a query tool; MySQL reports the error but does not always identify the exact subquery position. Simplify the query by removing subqueries one at a time until the error disappears.
Fix a scalar subquery by selecting only one column.
-- Broken: returns two columns in a scalar context SELECT name FROM orders WHERE customer_id = (SELECT id, email FROM customers WHERE email = 'alice@example.com'); -- Fixed: select only the column you need SELECT name FROM orders WHERE customer_id = (SELECT id FROM customers WHERE email = 'alice@example.com');Fix an IN clause with a multi-column subquery.
-- Broken SELECT * FROM orders WHERE customer_id IN (SELECT id, status FROM customers WHERE status = 'active'); -- Fixed SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE status = 'active');Fix a row value comparison by matching column counts.
-- Broken: left side has 2 columns, subquery returns 3 SELECT * FROM t WHERE (a, b) = (SELECT x, y, z FROM other WHERE id = 1); -- Fixed: match the number of columns on both sides SELECT * FROM t WHERE (a, b) = (SELECT x, y FROM other WHERE id = 1);Replace
SELECT *with an explicit column list inside any subquery used in a scalar or comparison context:-- Risky if the table has more than 1 column SELECT * FROM parent WHERE id = (SELECT * FROM child WHERE parent_id = 5); -- Safe SELECT * FROM parent WHERE id = (SELECT id FROM child WHERE parent_id = 5);For ORMs, inspect the generated SQL. Enable query logging to see the exact SQL sent to MySQL:
SET GLOBAL general_log = 'ON'; SET GLOBAL general_log_file = '/var/log/mysql/general.log';Then reproduce the error and inspect the log to find the offending generated query.
Additional Information
- The SQLSTATE for this error is
21000(cardinality violation), which is part of the SQL standard. Drivers and ORMs that map SQLSTATEs rather than vendor codes will report this as a cardinality violation. - Error 1241 is distinct from error 1242 (
ER_SUBQUERY_NO_1_ROW, SQLSTATE21000), which is raised when a scalar subquery returns more than one row rather than more than one column. Both share SQLSTATE21000but represent different structural problems. - MySQL does allow multi-column
INcomparisons using row constructors:(a, b) IN (SELECT x, y FROM ...)is valid as long as the row constructor and the subquery column count match exactly. - This error cannot be suppressed by SQL mode settings — it is a structural query error, not a data validation error, so
STRICT_TRANS_TABLESand similar mode flags have no effect.
Frequently Asked Questions
Why does my query work in PostgreSQL but fail in MySQL with error 1241? PostgreSQL is sometimes more permissive about implicitly handling row-valued expressions. MySQL strictly enforces that scalar contexts receive exactly one column. Review your subqueries and add explicit column lists.
Can a subquery in a JOIN produce error 1241?
No — a derived table (subquery in a FROM clause) can return any number of columns without triggering 1241. The error only occurs when a subquery is used in a scalar context: SELECT list, WHERE comparison, HAVING, or SET assignment.
What is the difference between error 1241 and error 1242?
Error 1241 means the subquery returned too many columns (wrong shape). Error 1242 means the subquery returned too many rows when exactly one row was expected. Both are cardinality errors but require different fixes — 1241 needs fewer columns in the SELECT list, while 1242 typically needs a LIMIT 1 or a more selective WHERE clause.
My ORM is generating the bad query — how do I trace it?
Enable the MySQL general query log (see the troubleshooting steps above), reproduce the error in your application, then grep the log for queries containing SELECT to find the exact SQL. In SQLAlchemy you can also set echo=True on the engine; in Hibernate set hibernate.show_sql=true.