Error SQL · agregaciones

GROUP BY y columnas no agrupadas: corrige la granularidad

Si GROUP BY falla en un motor o devuelve una columna difícil de interpretar, revisa qué representa una fila del grupo antes de añadir columnas a ciegas.

Lectura: 15–20 minComparativa por motorPráctica con pistas

El síntoma: GROUP BY falla en un motor o devuelve una columna que no sabes interpretar

Cuando una consulta agrupa filas, cada columna del resultado debe tener un significado inequívoco para cada grupo. Una columna seleccionada que no está agregada ni agrupada puede ser rechazada por el motor o, en motores permisivos, tomar un valor que no representa de forma fiable al grupo.

El diagnóstico correcto empieza por la granularidad: describe con palabras qué representa una fila del resultado.

Ejemplo problemático: categoría agrupada, producto suelto

SQL no portable
WITH ventas(categoria, producto, importe) AS (
  VALUES ('Audio', 'Auriculares', 40),
         ('Audio', 'Altavoz', 90),
         ('Oficina', 'Teclado', 60)
)
SELECT categoria,
       producto,
       SUM(importe) AS total
FROM ventas
GROUP BY categoria;

Para el grupo Audio existen dos productos. ¿Cuál debería mostrar la columna producto? PostgreSQL rechaza en general una referencia no agrupada que no sea funcionalmente dependiente; MySQL con ONLY_FULL_GROUP_BY —habilitado por defecto— aplica una comprobación equivalente. SQLite permite columnas “bare” y puede escoger un valor de una fila del grupo, por lo que aceptar la consulta no convierte ese producto en una descripción estable del grupo.

Corrige la consulta según la pregunta que quieres responder

Una fila por categoría

SQL portable
WITH ventas(categoria, producto, importe) AS (
  VALUES ('Audio', 'Auriculares', 40),
         ('Audio', 'Altavoz', 90),
         ('Oficina', 'Teclado', 60)
)
SELECT categoria,
       SUM(importe) AS total
FROM ventas
GROUP BY categoria
ORDER BY categoria;
Una fila por categoría
categoriatotal
Audio130
Oficina60

Una fila por categoría y producto

Si el producto forma parte de la unidad que quieres analizar, inclúyelo en el agrupamiento: GROUP BY categoria, producto. El resultado tendrá una granularidad distinta: una fila por pareja categoría-producto.

La dependencia funcional es una excepción que debes entender, no memorizar

Algunos motores pueden permitir una columna no escrita literalmente en GROUP BY si pueden demostrar que está determinada por las columnas agrupadas, por ejemplo mediante una clave. Esa regla no justifica seleccionar columnas arbitrarias. Para un alumno, la comprobación más segura sigue siendo preguntar: “¿puede haber más de un valor de esta columna dentro del mismo grupo?”.

Método de diagnóstico

  1. Nombra la granularidad: una fila por categoría, por cliente, por mes…
  2. Marca cada expresión del SELECT: agrupada, agregada o derivada de forma inequívoca.
  3. Busca columnas sueltas: si pueden tener varios valores dentro de un grupo, no describen una única fila agregada.
  4. No arregles el error añadiendo columnas a GROUP BY sin pensar: cada columna añadida puede dividir los grupos y cambiar la pregunta.

Práctica correctiva

Intermedia · agregaciones

Obtén una fila por categoría con número de productos y total

Con la CTE de ventas, devuelve categoria, el número de filas y la suma de importe. No muestres producto como columna suelta.

Qué debes recordar

  • Una consulta agregada necesita una granularidad clara.
  • No selecciones una columna con varios valores posibles dentro de un grupo.
  • PostgreSQL y MySQL estricto pueden rechazar la consulta; SQLite puede aceptarla con un valor no definido para la columna suelta.
  • Añadir columnas a GROUP BY cambia la granularidad y puede cambiar la pregunta.

Conceptos relacionados

Fuentes técnicas consultadas