Eftersom endast PK täcker alla kolumner i en underliggande tabell i GROUP BY klausul. Därför fungerar din första fråga. En UNIQUE begränsning gör det inte.
Kombinationen av en UNIQUE som inte kan uppskjutas och en NOT NULL begränsning skulle också kvalificera sig. Men det är inte implementerat - liksom några andra funktionella beroenden som är kända för SQL-standarden. Peter Eisentraut, huvudförfattaren till inslaget, hade mer i åtanke, men det fastställdes vid den tiden att efterfrågan är låg och associerade kostnader kan vara höga. Se diskussionen om funktionen på pgsql-hackers.
Manualen:
När
GROUP BYär närvarande, eller några aggregerade funktioner är närvarande, är det inte giltigt förSELECTlistuttryck för att hänvisa till ogrupperade kolumner förutom inom aggregerade funktioner eller när den ogrupperade kolumnen är funktionellt beroende av de grupperade kolumnerna, eftersom det annars skulle finnas mer än ett möjligt värde att returnera för en ogrupperad kolumn. Ett funktionellt beroende existerar om de grupperade kolumnerna (eller en delmängd därav) är den primära nyckeln i tabellen som innehåller den ogrupperade kolumnen.
Och mer explicit:
PostgreSQL känner igen funktionellt beroende (så att kolumner kan utelämnas från
GROUP BY) endast när en tabells primärnyckel ingår iGROUP BYlista. SQL-standarden specificerar ytterligare villkor som bör kännas igen.
Sedan c.vin är UNIQUE NOT NULL , kan du fixa din andra fråga genom att använda kolumnen PK istället:
...
group by c.id;
Bortsett från, medan referensintegritet upprätthålls och hela tabellen efterfrågas, kan båda de givna frågorna vara avsevärt billigare:aggregerade rader i appraisal före sammanfogningen. Detta tar bort behovet av att GROUP BY i den yttre SELECT a priori. Gilla:
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:
- Flera array_agg()-anrop i en enda fråga
Relaterat:
- SQL-sats som fungerar i MySQL fungerar inte i Postgresql - Sum &group_by rails 3
- PostgreSQL - GROUP BY-sats