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
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
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;| categoria | total |
|---|---|
| Audio | 130 |
| Oficina | 60 |
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
- Nombra la granularidad: una fila por categoría, por cliente, por mes…
- Marca cada expresión del SELECT: agrupada, agregada o derivada de forma inequívoca.
- Busca columnas sueltas: si pueden tener varios valores dentro de un grupo, no describen una única fila agregada.
- 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
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.
COUNT(*) y SUM(importe).Solución razonada
WITH ventas(categoria, producto, importe) AS (
VALUES ('Audio', 'Auriculares', 40),
('Audio', 'Altavoz', 90),
('Oficina', 'Teclado', 60)
)
SELECT categoria,
COUNT(*) AS productos,
SUM(importe) AS total
FROM ventas
GROUP BY categoria
ORDER BY categoria;Cada expresión describe ahora una única fila de categoría: el nombre del grupo y dos agregados calculados sobre sus filas.
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.