Porque solo el PK cubre todas las columnas de una tabla subyacente en el GROUP BY
cláusula. Por lo tanto, su primera consulta funciona. UN UNIQUE
la restricción no lo hace.
La combinación de un UNIQUE
no diferible y un NOT NULL
la restricción también calificaría. Pero eso no está implementado, así como algunas otras dependencias funcionales conocidas por el estándar SQL. Peter Eisentraut, el autor principal del artículo, tenía más en mente, pero en ese momento se determinó que la demanda es baja y los costos asociados podrían ser altos. Vea la discusión sobre la función en pgsql-hackers.
El manual:
Cuando GROUP BY
está presente, o cualquier función agregada está presente, no es válido para SELECT
Expresiones de lista para hacer referencia a columnas no agrupadas excepto dentro de funciones agregadas o cuando la columna no agrupada dependa funcionalmente de las columnas agrupadas, ya que de lo contrario habría más de un valor posible para devolver para una columna no agrupada. Existe una dependencia funcional si las columnas agrupadas (o un subconjunto de las mismas) son la clave principal de la tabla que contiene la columna no agrupada.
Y más explícitamente:
PostgreSQL reconoce la dependencia funcional (permitiendo que las columnas se omitan de GROUP BY
) solo cuando la clave principal de una tabla se incluye en GROUP BY
lista. El estándar SQL especifica condiciones adicionales que deben reconocerse.
Desde c.vin
es UNIQUE NOT NULL
, puede corregir su segunda consulta usando la columna PK en su lugar:
...
group by c.id;
Además, si bien se aplica la integridad referencial y se consulta toda la tabla, ambas consultas dadas pueden ser sustancialmente más económicas:filas agregadas en appraisal
antes la unión Esto elimina la necesidad de GROUP BY
en el exterior SELECT
a priori. Me gusta:
SELECT c.vin, c.color, c.brand
, a.min_appraisal
, a.max_appraisal
FROM car c
LEFT JOIN (
SELECT car_vin
, min(price) AS min_appraisal
, max(price) AS max_appraisal
FROM appraisal
GROUP BY car_vin
) a ON a.car_vin = c.vin;
Ver:
- Múltiples llamadas a array_agg() en una sola consulta
Relacionado:
- La declaración SQL que funciona en MySQL no funciona en Postgresql - Sum &group_by rails 3
- PostgreSQL - Cláusula GROUP BY