Fordi kun PK'en dækker alle kolonner i en underliggende tabel i GROUP BY
klausul. Derfor virker din første forespørgsel. En UNIQUE
begrænsning ikke.
Kombinationen af en UNIQUE
, der ikke kan udskydes og en NOT NULL
begrænsning ville også kvalificere sig. Men det er ikke implementeret - samt nogle andre funktionelle afhængigheder kendt af SQL-standarden. Peter Eisentraut, hovedforfatteren af indslaget, havde mere i tankerne, men det blev på det tidspunkt fastslået, at efterspørgslen er lav, og de tilknyttede omkostninger kan være høje. Se diskussionen om funktionen på pgsql-hackere.
Manualen:
Når GROUP BY
er til stede, eller der er aggregerede funktioner til stede, er den ikke gyldig for SELECT
listeudtryk for at referere til ugrupperede kolonner undtagen inden for aggregerede funktioner, eller når den ugrupperede kolonne er funktionelt afhængig af de grupperede kolonner, da der ellers ville være mere end én mulig værdi at returnere for en ugrupperet kolonne. Der eksisterer en funktionel afhængighed, hvis de grupperede kolonner (eller en undergruppe deraf) er den primære nøgle i tabellen, der indeholder den ugrupperede kolonne.
Og mere eksplicit:
PostgreSQL genkender funktionel afhængighed (tillader kolonner at blive udeladt fra GROUP BY
) kun når en tabels primære nøgle er inkluderet i GROUP BY
liste. SQL-standarden specificerer yderligere betingelser, der skal genkendes.
Siden c.vin
er UNIQUE NOT NULL
, kan du rette din anden forespørgsel ved at bruge kolonnen PK i stedet:
...
group by c.id;
Bortset fra, mens referentiel integritet håndhæves, og hele tabellen forespørges, kan begge de givne forespørgsler være væsentligt billigere:aggregerede rækker i appraisal
før sammenføjningen. Dette fjerner behovet for at GROUP BY
i den ydre SELECT
a priori. Ligesom:
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;
Se:
- Flere array_agg()-kald i en enkelt forespørgsel
Relateret:
- SQL-sætning, der fungerer i MySQL, virker ikke i Postgresql - Sum &group_by rails 3
- PostgreSQL - GROUP BY-klausul