GROUP BY: una fila por grupo
BásicoGROUP BY arma un grupo por cada combinación distinta de las columnas o expresiones indicadas y devuelve una fila por grupo. Toda columna del SELECT que no esté dentro de una función de agregación tiene que estar en el GROUP BY.
Sintaxis
SELECT columna_o_expresion, agregado(...)
FROM tabla
GROUP BY columna_o_expresion;Ejemplo
SELECT
to_char(date_trunc('month', o.created_at), 'YYYY-MM') AS mes,
count(*) AS pedidos,
sum(o.total_amount) AS ventas_uyu
FROM orders AS o
WHERE o.currency = 'UYU'
AND o.status = 'delivered'
AND o.created_at >= '2025-01-01'
AND o.created_at < '2025-07-01'
GROUP BY date_trunc('month', o.created_at)
ORDER BY mes;Resultado
| mes | pedidos | ventas_uyu |
|---|---|---|
| 2025-01 | 18 | 314030.56 |
| 2025-02 | 22 | 342997.08 |
| 2025-03 | 26 | 601294.47 |
| 2025-04 | 27 | 454021.36 |
| 2025-05 | 38 | 584296.44 |
| 2025-06 | 31 | 416597.86 |
Cómo leerlo
Cada fila es un mes del primer semestre de 2025 con los pedidos entregados en pesos uruguayos. Se agrupa por la expresión date_trunc('month', created_at), que lleva cada fecha al primer día de su mes; el to_char solo le da formato. Agrupar por la fecha completa daría casi una fila por pedido.
Error común
Así no
SELECT channel, status, count(*) AS pedidos
FROM orders
WHERE currency = 'UYU'
GROUP BY channel;Poner en el SELECT una columna que no está agrupada ni agregada. Dentro de un grupo de channel hay muchos status distintos y el motor no sabe cuál mostrar: PostgreSQL responde que status debe aparecer en el GROUP BY o dentro de una función de agregación. Agrégala al GROUP BY si quieres ese nivel de detalle.
En otros motores: PostgreSQL, MySQL, BigQuery, Snowflake
PostgreSQLMySQLBigQuerySnowflake
Aceptan
GROUP BY 1, 2(posición de la columna en elSELECT). Es cómodo para explorar, pero se rompe en silencio si alguien reordena elSELECT. SQL Server no lo acepta: hay que repetir la expresión completa.MySQL
Con el modo
ONLY_FULL_GROUP_BYdesactivado (viene activado desde la versión 5.7), MySQL acepta columnas sin agrupar y devuelve un valor cualquiera del grupo. El error de arriba pasa sin aviso.Snowflake
GROUP BY ALLagrupa por todas las columnas delSELECTque no son agregados (BigQuery y Databricks también lo tienen). PostgreSQL 18 no lo tiene.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.