Error SQL · forma de subconsultas

Subconsulta devuelve más de una columna: selecciona el dato que realmente necesitas

Una subconsulta usada como valor debe producir una sola columna. Si seleccionas dos o más, corrige la forma de la consulta: elige el dato escalar que necesitas o reescribe la comparación para expresar una relación entre varias columnas.

Lectura: 14–18 minEjemplo reproduciblePráctica con pistas

El síntoma: la consulta exterior esperaba un valor, pero la subconsulta devuelve una fila con varias columnas

Una subconsulta puede devolver muchas filas, muchas columnas o ambas cosas. El error de esta guía aparece cuando el contexto exterior necesita un valor escalar —por ejemplo, a la derecha de =— y la consulta interior selecciona dos o más columnas.

PostgreSQL define una subconsulta escalar como una consulta que devuelve exactamente una fila y una columna. MySQL muestra el error 1241 (21000): Operand should contain 1 column(s) en este tipo de uso. SQL Server documenta que una subconsulta introducida por un operador de comparación solo puede incluir una expresión o nombre de columna en su lista de selección. SQLite también distingue una subconsulta de una columna, que es escalar, de una subconsulta de varias columnas, que representa un valor de fila y solo puede utilizarse en contextos compatibles.

Ejemplo reproducible: una fila correcta, pero dos columnas de más

La subconsulta siguiente encuentra exactamente al cliente 1. El problema no es el número de filas: es que devuelve ciudad y activo cuando la expresión exterior solo está comparando ciudad.

SQL problemático
WITH clientes(id, nombre, ciudad, activo) AS (
  VALUES (1, 'Ana', 'Madrid', 1),
         (2, 'Luis', 'Madrid', 1),
         (3, 'Marta', 'Sevilla', 1),
         (4, 'Pablo', 'Madrid', 0)
)
SELECT id, nombre
FROM clientes
WHERE ciudad = (
  SELECT ciudad, activo
  FROM clientes
  WHERE id = 1
);

En una prueba local con SQLite esta forma falla con row value misused. En PostgreSQL y MySQL el diagnóstico equivalente señala que la subconsulta utilizada como valor no puede devolver más de una columna.

Corrección 1: selecciona solo la columna que necesita la comparación

Si la pregunta es «¿qué clientes viven en la misma ciudad que el cliente 1?», la subconsulta debe devolver únicamente ciudad.

SQL corregido
WITH clientes(id, nombre, ciudad, activo) AS (
  VALUES (1, 'Ana', 'Madrid', 1),
         (2, 'Luis', 'Madrid', 1),
         (3, 'Marta', 'Sevilla', 1),
         (4, 'Pablo', 'Madrid', 0)
)
SELECT id, nombre
FROM clientes
WHERE ciudad = (
  SELECT ciudad
  FROM clientes
  WHERE id = 1
)
ORDER BY id;
Resultado: clientes de la misma ciudad que Ana
idnombre
1Ana
2Luis
4Pablo

Corrección 2: si de verdad necesitas comparar varias columnas, expresa esa intención

A veces las dos columnas sí forman parte de la pregunta. Por ejemplo: «¿qué clientes tienen la misma ciudad y el mismo estado activo que el cliente 1?». En vez de intentar convertir dos columnas en un escalar, una opción portable y clara es correlacionarlas mediante EXISTS.

Comparación de dos atributos con EXISTS
WITH clientes(id, nombre, ciudad, activo) AS (
  VALUES (1, 'Ana', 'Madrid', 1),
         (2, 'Luis', 'Madrid', 1),
         (3, 'Marta', 'Sevilla', 1),
         (4, 'Pablo', 'Madrid', 0)
)
SELECT c.id, c.nombre
FROM clientes AS c
WHERE EXISTS (
  SELECT 1
  FROM clientes AS ref
  WHERE ref.id = 1
    AND ref.ciudad = c.ciudad
    AND ref.activo = c.activo
)
ORDER BY c.id;
Resultado cuando deben coincidir ciudad y estado activo
idnombre
1Ana
2Luis

Algunos motores admiten comparaciones de valores de fila. PostgreSQL, MySQL y SQLite tienen sintaxis para comparar tuplas o filas en determinados contextos. No la confundas con una subconsulta escalar: si escribes un valor escalar a la izquierda, la subconsulta de la derecha también debe tener forma escalar.

EXISTS es una excepción importante

EXISTS no consume los valores seleccionados: solo comprueba si la subconsulta devuelve alguna fila. Por eso puede verse SELECT * o una lista de columnas dentro de EXISTS sin que eso signifique que una subconsulta escalar acepte varias columnas. La pregunta es distinta: existencia de filas, no obtención de un valor.

Método de diagnóstico

  1. Ejecuta la subconsulta sola. Anota cuántas filas y cuántas columnas devuelve.
  2. Identifica la forma que exige el contexto. Una comparación escalar necesita un valor; EXISTS necesita saber si hay filas; una comparación de fila necesita componentes compatibles a ambos lados.
  3. Elimina columnas decorativas. No selecciones un id, nombre o estado adicional solo porque resulte útil para inspeccionar el dato.
  4. Separa el diagnóstico de la solución. Puedes ejecutar temporalmente varias columnas para depurar, pero la subconsulta final debe devolver la forma que la expresión exterior consume.

Error frecuente: confundir “más de una columna” con “más de una fila”

Son dos problemas de cardinalidad diferentes

Una subconsulta puede devolver una fila con dos columnas o dos filas con una sola columna. El primer caso se corrige ajustando la anchura del resultado o usando un contexto de fila; el segundo exige revisar cuántos registros puede producir y si necesitas IN, EXISTS o un valor realmente único. No uses LIMIT 1 para un problema de columnas: limitar filas no elimina columnas.

Práctica correctiva

Intermedia · subconsultas

Decide si necesitas una columna o dos condiciones

Con la misma tabla clientes, quieres devolver únicamente los clientes que comparten ciudad y estado activo con el cliente 1. Una subconsulta como ciudad = (SELECT ciudad, activo ...) falla. Reescribe la consulta sin perder ninguna de las dos condiciones.

Qué debes recordar

  • Una subconsulta escalar devuelve una sola columna.
  • Una fila con dos columnas no es lo mismo que dos filas con una columna.
  • Selecciona únicamente el dato que la expresión exterior necesita.
  • Si debes relacionar varios atributos, usa una forma que exprese esa relación, como EXISTS con condiciones explícitas.
  • EXISTS es diferente: comprueba filas y no utiliza los valores de su lista SELECT.

Conceptos relacionados

Fuentes técnicas consultadas