Perché solo il PK copre tutte le colonne di una tabella sottostante in GROUP BY
clausola. Quindi la tua prima query funziona. Un UNIQUE
vincolo no.
La combinazione di un UNIQUE
non differibile e un NOT NULL
anche il vincolo si qualificherebbe. Ma questo non è implementato, così come alcune altre dipendenze funzionali note allo standard SQL. Peter Eisentraut, l'autore principale del film, aveva in mente di più, ma all'epoca era determinato che la domanda fosse bassa e che i costi associati potessero essere elevati. Vedi la discussione sulla funzione su pgsql-hacker.
Il manuale:
Quando GROUP BY
è presente, o sono presenti funzioni aggregate, non è valido per SELECT
list le espressioni per fare riferimento a colonne non raggruppate tranne all'interno di funzioni aggregate o quando la colonna non raggruppata dipende funzionalmente dalle colonne raggruppate, poiché altrimenti ci sarebbe più di un valore possibile da restituire per una colonna non raggruppata. Esiste una dipendenza funzionale se le colonne raggruppate (o un loro sottoinsieme) sono la chiave primaria della tabella contenente la colonna non raggruppata.
E più esplicitamente:
PostgreSQL riconosce la dipendenza funzionale (consentendo che le colonne siano omesse da GROUP BY
) solo quando la chiave primaria di una tabella è inclusa nel GROUP BY
elenco. Lo standard SQL specifica condizioni aggiuntive che devono essere riconosciute.
Da c.vin
è UNIQUE NOT NULL
, puoi correggere la tua seconda query utilizzando invece la colonna PK:
...
group by c.id;
A parte, mentre viene applicata l'integrità referenziale e viene interrogata l'intera tabella, entrambe le query fornite possono essere sostanzialmente più economiche:righe aggregate in appraisal
prima l'unione. Questo elimina la necessità di GROUP BY
nel SELECT
esterno a priori. Come:
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;
Vedi:
- Più chiamate array_agg() in una singola query
Correlati:
- Istruzione SQL funzionante in MySQL non funzionante in Postgresql - Sum &group_by rails 3
- PostgreSQL - clausola GROUP BY